simondotm / nx-firebase

Firebase plugin for Nx Monorepos
https://www.npmjs.com/package/@simondotm/nx-firebase
MIT License
180 stars 31 forks source link

Firebase Executor for emulator suite #9

Closed KingDarBoja closed 3 years ago

KingDarBoja commented 3 years ago

Hi, awesome plugin, been using it a bit for experimenting with sharing code between firebase functions and angular apps.

Wanted to know if the firebase executor can be documented or configured to support emulators parameters.

Right now I am doing something like below at angular.json for serve the CF locally with emulators.

{

        "serve": {
          "builder": "@nrwl/workspace:run-commands",
          "options": {
            "commands": [
              {
                "command": "nx run appName:build"
              },
              {
                "command": "firebase use projectIdOrAlias"
              },
              {
                "command": "firebase emulators:start --config firebase.appName.json"
              }
            ],
            "parallel": false
          }
        }
}

Cheers!

simondotm commented 3 years ago

Hi, thanks for the feedback. I actually think your approach there is a practical solution, making good use of the run-commands executor. I didn't want to add complexity to the plugin that would be trying to second guess how different folks use firebase in their workflow, since there are a few variables - which project to use, should it build before serving etc.

One simple thing I guess we could consider is having a convenience generator that would add a "serve" target like this to an existing app, that would take the projectIdOrAlias variable as an option.

KingDarBoja commented 3 years ago

I forgot to mention that trying to run the emulators will yield an error and abort such operation:

image

Not sure if related to the library setup itself as it is the first time I encountered the error.

simondotm commented 3 years ago

Ok thanks for the extra info, I've not used the emulators so far, so this is a good opportunity to get more familiar with them

KingDarBoja commented 3 years ago

Btw, looks like the issue was caused by the empty hosting rule inside the firebase.appName.json file. So either comment the hosting emulator or set the config to properly initialize it.

Also, I got the following warning:

The Cloud Functions emulator requires the module "firebase-admin" to be installed as a dependency. To fix this, run "npm install --save firebase-admin" in your functions directory. i functions: Your functions could not be parsed due to an issue with your node_modules (see above)

So I added both firebase-admin and firebase-functions to the package.json inside the firebase app to avoid it:

  "dependencies": {
    "firebase-admin": "^9.8.0",
    "firebase-functions": "^3.14.1"
  },

image

simondotm commented 3 years ago

Sweet! You got it working! Thanks for sharing that. Interesting about that firebase-admin dep, because Max mentioned a similar (unrelated issue) with that too -https://github.com/simondotm/nxfirebase/issues/7#issue-891665170 Ok I think I'll change the package template to somehow have admin and functions deps in as a default. I didn't want to put them in the template since they'll not get overwritten if versions in the root package get updated, I'll figure it out though. Thanks again.

simondotm commented 3 years ago

Or I could import firebase-admin in the default index.ts... hmm (all of my functions do import firebase-admin at some point, so I didn't see this occur until these examples came up)

KingDarBoja commented 3 years ago

Or I could import firebase-admin in the default index.ts... hmm (all of my functions do import firebase-admin at some point, so I didn't see this occur until these examples came up)

Ummmm... I accidentally removed it while testing the grouped functions feature, I can give it a try like that.

Also noticed that I must keep an empty firebase.json file at root and move the hosting config to the project specific json file to properly initialize the hosting emulator.

UPDATE 1

Yeah, seems like adding the following code does that:

// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
import * as functions from 'firebase-functions';

// The Firebase Admin SDK to access Cloud Firestore.
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);

// Set up extra settings. Since May 29, 2020, Firebase Firebase Added support for
// calling FirebaseFiresore.settings with { ignoreUndefinedProperties: true }.
// When this parameter is set, Cloud Firestore ignores undefined properties
// inside objects rather than rejecting the API call.
admin.firestore().settings({
  ignoreUndefinedProperties: true,
});

So there is no need to specify the dependencies in the app package.json.

UPDATE 2

It is my experimental workspace and I am pretty happy with the emulator and whole setup with this plugin: ngfire-showcase. Don't expect too much there as wanted to give it a quick trial to this plugin, but so far so good! 🚀

simondotm commented 3 years ago

Also noticed that I must keep an empty firebase.json file at root and move the hosting config to the project specific json file to properly initialize the hosting emulator. I will share my example nx workspace in a few minutes.

There's a note in the readme about this - if you are only using one firebase application in your nx workspace, you can just delete the empty firebase.json and rename your firebase.appname.json to just firebase.json (and this way you dont need the --config part in firebase CLI commands) The only reason the empty firebase.json is there is to stop the CLI moaning!

simondotm commented 3 years ago

This is all great feedback, thanks. I'll incorporate these improvements into the next release.

simondotm commented 3 years ago

Also @KingDarBoja - thanks for the ignoreUndefinedProperties: true tip - I wasn't aware of this little gem, drives me nuts when there's exceptions due to an undefined field creeping in somewhere!

simondotm commented 3 years ago

Hey @KingDarBoja - can I ask why you have the firebase use projectIdOrAlias command in your serve target? I'm trying to understand if that is required for the emulators to work? (since the firebase use command selects a remote deployment instance, not a local instance)

Would it work with just:

            "commands": [
              {
                "command": "nx run appName:build"
              },
              {
                "command": "firebase emulators:start --config firebase.appName.json"
              }
            ],
simondotm commented 3 years ago

v0.2.3 now released against Nx version 12.3.4

Ok I've added serve and deploy targets to the application generator which support the use cases above. I dont have a migration script for the plugin so existing NxFirebase apps will need to manually change their targets as follows:

        "serve": {
          "executor": "@nrwl/workspace:run-commands",
          "options": {
            "commands": [
              {
                "command": "nx run appname:build --watch"
              },
              {
                "command": "firebase emulators:start --config firebase.appname.json"
              }
            ],
            "parallel": true
          }
        },
        "deploy": {
          "executor": "@nrwl/workspace:run-commands",
          "options": {
            "command": "firebase deploy --config firebase.appname.json"
          }
        },
simondotm commented 3 years ago

@KingDarBoja - Please note project has now been renamed to @simondotm/nx-firebase, see here for the new 0.3.0 release.

KingDarBoja commented 3 years ago

Hey @KingDarBoja - can I ask why you have the firebase use projectIdOrAlias command in your serve target? I'm trying to understand if that is required for the emulators to work? (since the firebase use command selects a remote deployment instance, not a local instance)

Would it work with just:

            "commands": [
              {
                "command": "nx run appName:build"
              },
              {
                "command": "firebase emulators:start --config firebase.appName.json"
              }
            ],

Because the cli will start blaming and stop the emulators execution with the following error:

emulators: The Emulator UI requires a project ID to start. Configure your default project with 'firebase use' or pass the --project flag.
KingDarBoja commented 3 years ago

@simondotm tried the latest version (0.3.1) and the emulators are working perfectly. No clue why the previous error was showing up regarding the project id but seems it is already picking the default one :)

image