Coder Social home page Coder Social logo

fireway's People

Contributors

dependabot[bot] avatar heldersi avatar josheverett avatar jozefcipa avatar kevlened avatar kiptoomm avatar mxmalykhin avatar nicholaiii avatar psilospore avatar ykns avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

fireway's Issues

Allow for extra files

It would be really great if fireway didn't throw when encountering files that didn't meet the migration filename spec. This would allow for configuration files and helpers relevant to migrations to co-exist in the migrations folder.
Maybe just return null like when the filename doesn't comply with semver.

throw new Error(`This filename doesn't match the required format: ${filename}`);

upgrade dependencies

Your package raises a lot of security alerts in your repo. Can you upgrade your dependencies to your latest version?

fireway requiring projectId while running against firebase emulator

Hi there,

I'm currently running into an issue attempting to run migrations whilst specifying the environment variable FIREBASE_EMULATOR_HOST, my script is something along the lines of;

    "emulators": "firebase emulators:start",
    "firebase-migration": "yarn cross-env FIRESTORE_EMULATOR_HOST=localhost:8080 fireway --path=\"./scripts/migrations\" migrate --dryRun"

on starting the emulator, then running firebase-migration I get this error;

 FirebaseAppError: Failed to determine project ID: Error while making request: getaddrinfo ENOTFOUND metadata.google.internal. Error code: ENOTFOUND

which is quite strange considering the README file for the package explicitly states that once the FIRESTORE_EMULATOR_HOST env value is set, there should be no need to set a project ID, I also looked into how tests are ran in package, and I see it's very similar to the setup I shared above. I'd appreciate any insights you might have as why it's not working as one might expect.

My fireway version is 1.1.0

Failed to read credentials

I'm trying to run migration script, but unfortunately it cannot read my credentials.

Currently using

set GOOGLE_APPLICATION_CREDENTIALS="%cd%\google-services.json"
fireway migrate

results in

ERROR: Failed to read credentials from file "C:\Users\[...]\google-services.json": Error: ENOENT: no 
such file or directory, open '"C:\Users\[...]\google-services.json"

Also when setting a relative path (they're in the same folder) set GOOGLE_APPLICATION_CREDENTIALS="google-services.json" does not fix it

Noisy migrations

I've just run my first migration and there was a lot of output. It looks like in cli.js that debug is set to true with no other possible value. This triggers all the logging behaviour.

Would you be OK with receiving a PR that adds a --debug flag to the CLI?

Example Project / Documentation

Hey @kevlened, I really love that you've solved a problem I (and I imagine many others) have found ourselves with. I was wondering if you had an open-source project to show how this actually looks in practice (for example: how to handle failed migration data rollbacks, formatting longer descriptions in the migration filename, etc).

More than happy to help set up a skeleton project if that would help, but I wanted to see if you had something open already to look at. Thanks

"Unexpected token ." when running fireway

Hi! Thanks for the library. Unfortunately, I run into an issue when running fireway migrate

.nvm/versions/node/v10.22.0/lib/node_modules/fireway/src/index.js:31
		while (this._fireway_queue?.length) {
		                           ^

SyntaxError: Unexpected token .

Does it mean only Node.js versions that support optional chaining are supported?

Unexpected token '.'

I'm getting Unexpected token '.' when running npx fireway. Version 0.4.2 is the latest working version for me.

use with the firestore emulator

Is there any way to use this library against a local instance of firestore running in the emulator? I'd love to test migration scripts against my local instance running at http://localhost:4000/firestore but when I do:
fireway migrate

I get:

Found 2 migration files
ERROR: 9 FAILED_PRECONDITION: The Cloud Firestore API is not available for Cloud Datastore projects.

I thought that maybe it needs the --projectId option but I wouldn't know which 'project' to use since the target database is on a [locally] emulated instance. Any ideas?

Problem with forceWait

I have a problem with forceWait. When I run migrations with forceWait fireway runs only the first migration and stops working after that without writing migration result to firestore. Without forceWait I works as expected but I get a lot of warnings. Any idea what's going on?

Example migration:

import { firestoreRoutes } from '@travel-together/core/routes';
import { MigrateOptions } from 'fireway';
import { createTraverser } from '@firecode/admin';

export const migrate = async ({ firestore, FieldValue }: MigrateOptions) => {
  const usersCollection = firestore
    .collection(firestoreRoutes.users)
    .where('active', '==', true)
    .where('deleted', '==', false);
  const storiesCollection = firestore.collection(firestoreRoutes.stories);
  const usersTraverser = createTraverser(usersCollection);

  const { docCount } = await usersTraverser.traverse(
    async (batchDocs, batchIndex) => {
      const batchSize = batchDocs.length;
      for (const doc of batchDocs) {
        const userData = doc.data();
        const storyData = {
          creatorId: doc.id,
          createdAt: userData.createdAt,
          lastActivityAt: userData.createdAt,
        };
        await storiesCollection.add(storyData);
        await doc.ref.update({
          numStories: FieldValue.increment(1),
        });
      }
      console.log(
        `Batch ${batchIndex} done! Migrated ${batchSize} users in this batch.`,
      );
    },
  );

  console.log(`Migrated ${docCount} users`);
};

Running locally doesn't read/write the latest data

Hello,
This is a great tool! So, thanks!

I ran into this problem when I was figuring out how this package works, and it made it really difficult to figure out what I needed to do!
I also don't have a solution to it, other than a lot of emulator reloads.

I tried running a migration against my local emulators, but it only ever returned 1 document.
I exported the data from my emulators, restarted them and re-imported the data, then the migration found the additional documents.
I think I had 1 document in the collection I was migrating when I first loaded the emulators and dry-ran the migration. I then added more documents for more testing, which it never picked up.
I had to export the new data from the emulators, restart the emulators, then reimport the data for it to be picked up by fireway.

Also, the saved migration details seemed to disappear, but still function for fireway.
So, I would run a v0.0.1 migration against the local emulators. It would do its thing.
No new collection called fireway would turn up in the emulators, however fireway would no longer run that migration version.
I looked through all my firebase projects in case it had leaked to a dev/prod project, however I didn't see it in any of them.

Once I confirmed my migrations (with lots of emulator restarts), everything ran fine on my dev/prod projects.

trouble running document *field* deletion migrations

Based on the official docs, I have been trying to implement a migration that removes some deprecated fields in my documents. Here's the error I have consistently faced:

Update() requires either a single JavaScript object or an alternating list of field/value pairs that can be followed by an optional precondition. Value for argument "dataOrField" is not a valid Firestore document. Couldn't serialize object of type "DeleteTransform" (found in field "test1"). Firestore doesn't support JavaScript objects with custom prototypes (i.e. objects that were created via the "new" operator).

Here's the minimal code that reproduces the error (this same code works as expected when run as a script of its own, or when it's executed from a REST endpoint function):

// ./migrations/v0.0.1__test_field_deletion.js
const { admin } = require("firebase-admin");

const FieldValue = admin.firestore.FieldValue;

/**
 * remove deprecated fields were left behind by previous migrations
 */

module.exports.migrate = async ({ firestore }) => {
  try {
    // Get the `FieldValue` object
    const FieldValue = admin.firestore.FieldValue;

    // Grab the doc id.
    const docId = "1i9oM3IWWI2Q2VU5Pzjp";
    // Grab the collection name
    const collName = "consignments";
    // Create a document reference
    const docRef = firestore.collection(collName).doc(docId);
    let docItem = await docRef.get();

    const payload = {
      test1: FieldValue.delete()
    };

    console.log("payload ==> ", payload); // { test1: DeleteTransform {} }
    const res = await docRef.update(payload); // run the actual update op to delete the field
    console.log("deletion result: ", res);
  } catch (error) {
    console.log("error performing field delete migration: ", error.toString());
  }
};

Any ideas on how I can get it working with fireway?

My stack:

  • macOS Catalina
  • fireway --version = 0.4.0
  • node --version = v14.3.0

Typescript: Incorrect type for FieldValue

Imagine you have this (Renamed FieldValue to fv to avoid confusion below).

function migrate({ firestore, FieldValue: fv }: MigrateOptions) {}

So in this case, if you do something like

const timestamp = fv.serverTimestamp()

Typescript will complain: Property serverTimestamp is a static member of type FieldValue.

It's because fv is typed as instance of class FieldValue, not the class FieldValue itself.

The solution would be to type it like this FieldValue: typeof FieldValue.

I haven't checked, but it might be the case for FieldPath and Timestamp as well.

"fireway detected open async calls" when creating documents

For some reason, I keep getting warnings that "fireway detected open async" calls whenever I create a document in a migration.
All of these example migrations that do manage their async calls properly, are getting that warning.

module.exports.migrate = async ({ firestore: db }) => {
    await db.collection('test').add({ foo: 'bar' });
};
module.exports.migrate = async ({ firestore: db }) => {
    await db.collection('test').doc().set({ foo: 'bar' });
};
module.exports.migrate = ({ firestore: db }) => {
   db.collection('test').doc();
};

Suport typescript for migration scripts

I'm not a very good with javascript/typescript, so maybe I'm talking nonsense.

It would be lovely to be able to write the migration scripts in typescript.
I've tried it, and got a syntax error when trying to import.

Is it possible to support typescript?

Parses hidden migration files and errors

vi creates .*swp files while editing. So when I'm developing the migration script and I run fireway with --dryrun, I get the following error:

ERROR: Both v0.0.1__move-data-from-user-to-profile.js and .v0.0.1__move-data-from-user-to-profile.js.swp have the same version

My expectation is that files with a leading . would be ignored.

Thanks for this tool! I'm not sure how database migrations is completely ignored by the firebase CLI tool / firestore team.

Wait for migrations with async calls, even if they don't return a Promise

The following migration script has an error in it. serverTimestamp is missing parens.

module.exports.migrate = ({firestore, FieldValue}) => {
  firestore.collection("users").get()
    .then((querySnapshot) => {
      querySnapshot.forEach(async (queryDocumentSnapshot) => {
        const id = queryDocumentSnapshot.id;
        const data = queryDocumentSnapshot.data();

        await firestore.collection("profiles").doc(id).set({
          createdAt: FieldValue.serverTimestamp,
          userId: id
        }); 
      });
    });
};

Dryrun does not catch this. It may be difficult for fireway to be able to detect such errors.

But what this issue is about is that the document stored by fireway sets success to true even though this error is thrown:

(node:19102) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 63)
(node:19102) UnhandledPromiseRejectionWarning: Error: Cannot encode value: serverTimestamp() {
        return ServerTimestampTransform.SERVER_TIMESTAMP_SENTINEL;
    }

My expectation is that the fireway document would set success to false.

This is low priority as my understanding is that fireway, whether success is true or false, will not process the migration again until I remove this document.

Thanks.

Running migrations with '--dryrun' modifies the db sometimes.

I noticed an inconsistency when running migration scripts with the --dryrun option.
I was testing out my code to copy data from one collection to a new one. Whenever a change to the script was made, I ran the migration script which worked as expected on most occasions but made changes to the db sometimes.
The new collection is created and the supplied data is added.

The expected behaviour is that the new collection should not be created when using --dryrun.

Command ran: fireway migrate --dryrun
Fireway [email protected]
Node: v14.16.0
OS: macOS Catalina

How to run a specific migration file?

Is there a way to run a specific migration if I have multiple scripts living in my migrations/ folder? Lately, I have had a few use cases where I need to re-run a script whose entry is already in the fireway collection on Firestore. However, to actually make a script to be executed, I have found that I have to manually delete the entry corresponding to that script and others that came after it. For example, let's say I have:

migrations/v0.0.1__first_migration.js
migrations/v0.0.2__second_migration.js
migrations/v0.0.3__third_migration.js

If I need to run just v0.0.2__second_migration.js, I have to delete both the corresponding v2 and v3 entries in the fireway collection and then rerun fireway migrate. Wouldn't it be nice if I could do something like fireway migrate --script=v0.0.2?

Don't understand how to use this tool.

I need to do a migration and would love to use this tool but the README is not very helpful. Can you do a tutorial or add more documentation?

I installed yarn then tried yarn add -G fireway but it said error Missing list of packages to add to your project.

Configure Firestore Settings throws error

I want to configure my firestore settings for a specific migration. I need to set "ignoreUndefinedProperties: true". When I do this within the migrate function, I receive an error that Firestore has already been initialized. Is there a way to configure firestore settings?

export async function migrate({firestore} : MigrateOptions) {
  firestore.settings({ timestampsInSnapshots: true, ignoreUndefinedProperties: true });
  ...
}

Need Support for ES6 Module -> (Error [ERR_REQUIRE_ESM]: require() of ES Module)

Hey, I'm done searching for firestore migration, and just found this great tools. But seems only support for CommonJS.

Can I use ES6 module import ? because I faced this error when i'm using ES6 Module import.

Screenshot 2023-11-22 203555

v0.0.1__foods.js

import * as fs from 'fs';
import * as path from 'path';

async function migrate({ firestore, FieldValue }) {
  const foods = JSON.parse(fs.readFileSync(path.resolve('src/seeds/foods.json')));

  foods.forEach(async (item) => {
    await firestore.collection('foods').doc(item.id).set(item);
  });
}

export default migrate;

Reverse migrations

Hi,

Have you had any thoughts on how you might want to do reverse migrations? I'm likely to have some time to implement this and would want to do it in a way that lines up with your plans.

How to access admin.auth()?

Is it even possible to access the admin object from the migration script?

I want to change some filed names inside customUserClaims, so I thought it would be nice to create a migration for that. But for doing that I would need to access admin.auth().listUsers() and then run setCustomUserClaims() for each individual user.

I've added const admin = require("firebase-admin"); before the script, which amazingly worked, but that feels like a workaround and not a proper solution.

I would suggest adding admin object to MigrateOptions

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.