angular / angularfire

Angular + Firebase = ❤️
https://firebaseopensource.com/projects/angular/angularfire2
MIT License
7.69k stars 2.19k forks source link

Function Dependencies Causing Build To Fail #3025

Open firstlinestudio opened 3 years ago

firstlinestudio commented 3 years ago

Version info

Angular: 12.2.29

Firebase: 9.1.2 / 9.1.3

AngularFire: 7.1.0 / 7.1.1

Other (e.g. Ionic/Cordova, Node, browser, operating system): Windows Terminal / PowerShell

How to reproduce these conditions

Failing test unit, Stackblitz demonstrating the problem

Steps to set up and reproduce

In any terminal / powershell, run: ng deploy. The process will run until it attempts to upload the function. The function fails to deploy.

Sample data and security rules

package.json created in dist/{PROJECT_NAME}/functions

  "dependencies": {
    "firebase-admin": "^9.11.1",
    "firebase-functions": "^3.6.0",
    "{PROJECT_NAME}": "file:..\\..\\.."
  },

Debug output

Errors in Windows Terminal

Error when trying to deploy: Functions did not deploy properly.

Error output from Google Cloud Builder Log "Step #1 - "build": Failure: (ID: XXXXXX) npm ERR! @angular-devkit/architect not accessible from {PROJECT_NAME}"

Expected behavior

To deploy successfully. Using 7.1.0-rc.4, the dist package.json does not try to access root dependencies and deploys successfully.

Actual behavior

Project will not deploy with cloud functions

jasonbdt commented 3 years ago

Have the same problem, already tried to find a fix for it but have no solution right now. There are also many warning messages while trying to deploy. I think this causes the problem but I'm not sure.

firstlinestudio commented 3 years ago

I deleted the node_modules folder and removed everything from the root package.json. I then created a new set of dependencies. I now get a new error while trying to deploy:

Build failed: npm ERR! The npm ci command can only install with an existing package-lock.json or npm ERR! npm-shrinkwrap.json with lockfileVersion >= 1. Run an install with npm@5 or npm ERR! later to generate a package-lock.json file, then try again.

Here is the current package.json from the project root folder (main package.json):

{
  "name": "sample",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "dev:ssr": "ng run sample:serve-ssr",
    "serve:ssr": "node dist/sample/server/main.js",
    "build:ssr": "ng build && ng run sample:server",
    "prerender": "ng run sample:prerender"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^12.0.0",
    "@angular/cdk": "^12.0.0",
    "@angular/common": "^12.0.0",
    "@angular/compiler": "^12.0.0",
    "@angular/core": "^12.0.0",
    "@angular/fire": "^7.1.1",
    "@angular/forms": "^12.0.0",
    "@angular/material": "^12.0.0",
    "@angular/platform-browser": "^12.0.0",
    "@angular/platform-browser-dynamic": "^12.0.0",
    "@angular/platform-server": "^12.0.0",
    "@angular/pwa": "^12.0.0",
    "@angular/router": "^12.0.0",
    "@angular/service-worker": "^12.0.0",
    "@nguniversal/express-engine": "^12.1.1",
    "cross-fetch": "^3.1.4",
    "express": "^4.15.2",
    "firebase": "^9.1.0",
    "lodash.isequal": "^4.5.0",
    "rxfire": "^6.0.0",
    "rxjs": "^6.6.0",
    "tslib": "^2.1.0",
    "webpack": "^5.35.0",
    "zone.js": "^0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/architect": "^0.1200.0",
    "@angular-devkit/build-angular": "^12.0.0",
    "@angular/cli": "^12.0.0",
    "@angular/compiler-cli": "^12.0.0",
    "@nguniversal/builders": "^12.1.0",
    "@types/express": "^4.17.0",
    "@types/jasmine": "^3.6.0",
    "@types/node": "^12.11.1",
    "file-loader": "^6.2.0",
    "firebase-admin": "^9.11.1",
    "firebase-functions": "^3.6.0",
    "firebase-functions-test": "^0.2.2",
    "firebase-tools": "^9.20.0",
    "fuzzy": "^0.1.3",
    "inquirer": "^6.2.2",
    "inquirer-autocomplete-prompt": "^1.0.1",
    "jasmine-core": "^3.8.0",
    "jasmine-spec-reporter": "^7.0.0",
    "jsonc-parser": "^3.0.0",
    "karma": "^6.3.0",
    "karma-chrome-launcher": "^3.1.0",
    "karma-coverage": "^2.0.3",
    "karma-jasmine": "^4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "ng-packagr": "^12.0.0",
    "open": "^7.0.3",
    "ts-node": "^9.1.1",
    "tslint": "^6.1.3",
    "typescript": "^4.2.3",
    "webpack-bundle-analyzer": "^4.4.1"
  },
  "resolutions": {
    "webpack": "^5.35.0"
  }
}

The dist/sample/functions folder does have a generated package.json and package-lock.json, so not sure why the cloud builder is not able to access or detect that they exist.

firstlinestudio commented 3 years ago

The project runs, when using deploy --preview but refreshing any page will result in an error: "Cannot GET URL /this/page". Using npm run dev:ssr the project runs as expected and there is no error when a page is refreshed.

firstlinestudio commented 3 years ago

@jasonbdt I found (A / THE) solution, but you may not like it. You'll have to do some downgrading so that all your dependencies can build properly. Here's what I did:

I believe those are the main three. I was able to keep angular (core, common, fire, material, etc..) at the latest versions. Be sure to change the "functionsNodeVersion": "14" line to read "14" and not "12" or "16"; so that it will match the node version installed on your PC.

jasonbdt commented 3 years ago

@firstlinestudio Well, my environment runs on the following setup:

My Angular is at Version 12.2.0. When I want to update with ng update it says that I am already at latest version, except @angular/fire because >= 7.1.0 causes ng deploy to throw errors. I downgraded this package to 7.0.4 to make it work again. My functionsNodeVersion already is set to 14.

Are you sure that NodeJS and NPM causes the error?

firstlinestudio commented 3 years ago

@jasonbdt I'm sure that is what fixed my deploy issue, but it didn't not fix the project all together. I now have an issue with the SSR function not retrieving URLs. Every URL except root will return a "cannot get URL /sample/url" message when trying to access through the function. I can navigate the site just fine, but if I refresh a page -- other than the root homepage -- it will throw an error. That is in development. In production, the message shows Error Forbidden: Your client does not have permission to get URL /ssr_sample/url1/url2 from this server. . I am still working on a solution.

firstlinestudio commented 3 years ago

The project is back to working fully. firebase-tools was installed globally and locally (in the project). I removed the local package since that is not needed. I also had to update @angular-devkit/architect using npm install @angular-devkit/architect@latest. That fixed the development build problems. I had to disable cloud functions, then re-enable cloud functions to get the production build to work (using Google Cloud Web Console). Finally, I removed "region": "us-central1", from the angular.json file, under the "deploy" settings.

The moral of the story is to manage dependencies properly. I'm not sure if it is listed in the docs, but it would be useful to add "optimal" package versions somewhere (i.e. use nodejs 14, not nodejs 16) and/or have an optimal package.json available for the latest build. I recommend NOT doing a general npm update on the root package.json, since having the latest versions of all packages doesn't always seem to work as well as expected.

jasonbdt commented 2 years ago

@firstlinestudio of course, if you have installed firebase-tools globally you can remove the local package. I guess the developers doesn't suppose everyone to have firebase-tools installed globally, thats why they added it as local package which makes sense for me.

As far as I know @angular-devkit/architext have to be in a version which mirrors the version of the core like shown below:

"devDependencies": {
    "@angular-devkit/architect": "^0.1401.0",
    "@angular-devkit/build-angular": "^14.1.0",
}

The region option inside angular.json is only interesting if you want to use another region to upload your cloud function. If you are fine using us-central1, you can remove this as it's the default region.

When I use ng deploy the CLI creates a /dist/functions directory for me. Inside this directory there is a package.json. For any reason, @angular/fire is not even writing "[PACKAGE NAME]": "file:..\..\.." under dependencies section. My package.json generated by the CLI looks like this:

{
  "name": "functions",
  "description": "Angular Universal Application",
  "main": "index.js",
  "scripts": {
    "start": "firebase functions:shell"
  },
  "engines": {
    "node": "14"
  },
  "dependencies": {
    "firebase-admin": "^9.11.1",
    "firebase-functions": "^3.6.0"
  },
  "devDependencies": {},
  "private": true
}

If all files created by the CLI for uploading to Cloud Functions, the command tries to install the dependencies named inside the /dist/functions/package.json file. After that the upload begins and our cloud function should be updated. The upload process will throw an error, because the required angular packages can not be found.

Because of this, I have to mirror the dependencies section of my root package.json into /dist/functions/package.json, move into this directory and reinstall the packages manually by using npm install. After that I can move back into my root directory with the terminal and run firebase deploy. This workaround works for me.

I have also copied this repository and build a custom version of it with some code changes to make ng deploy work again. After some trial and error I found a solution. I will do some more testing and if everything still works as expected, I will make a pull request to fix this.

Sincerly Jason

sidsaxena0 commented 2 years ago

@firstlinestudio of course, if you have installed firebase-tools globally you can remove the local package. I guess the developers doesn't suppose everyone to have firebase-tools installed globally, thats why they added it as local package which makes sense for me.

As far as I know @angular-devkit/architext have to be in a version which mirrors the version of the core like shown below:

"devDependencies": {
    "@angular-devkit/architect": "^0.1401.0",
    "@angular-devkit/build-angular": "^14.1.0",
}

The region option inside angular.json is only interesting if you want to use another region to upload your cloud function. If you are fine using us-central1, you can remove this as it's the default region.

When I use ng deploy the CLI creates a /dist/functions directory for me. Inside this directory there is a package.json. For any reason, @angular/fire is not even writing "[PACKAGE NAME]": "file:..\..\.." under dependencies section. My package.json generated by the CLI looks like this:

{
  "name": "functions",
  "description": "Angular Universal Application",
  "main": "index.js",
  "scripts": {
    "start": "firebase functions:shell"
  },
  "engines": {
    "node": "14"
  },
  "dependencies": {
    "firebase-admin": "^9.11.1",
    "firebase-functions": "^3.6.0"
  },
  "devDependencies": {},
  "private": true
}

If all files created by the CLI for uploading to Cloud Functions, the command tries to install the dependencies named inside the /dist/functions/package.json file. After that the upload begins and our cloud function should be updated. The upload process will throw an error, because the required angular packages can not be found.

Because of this, I have to mirror the dependencies section of my root package.json into /dist/functions/package.json, move into this directory and reinstall the packages manually by using npm install. After that I can move back into my root directory with the terminal and run firebase deploy. This workaround works for me.

I have also copied this repository and build a custom version of it with some code changes to make ng deploy work again. After some trial and error I found a solution. I will do some more testing and if everything still works as expected, I will make a pull request to fix this.

Sincerly Jason

Have you been able to solve it in your new repository, this issue is too old and it's sad there is still no solution for this.

jasonbdt commented 2 years ago

Have you been able to solve it in your new repository, this issue is too old and it's sad there is still no solution for this.

Yes, I was able to find a solution but sadly I had no time to test it properly to check if my solution would break anything else.

nicky-lenaers commented 1 year ago

@jasonbdt Would you be able to share your solution by any chance?