Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Has anyone successfully deployed yet? #343

Open
signalprime opened this issue Jul 18, 2019 · 11 comments
Open

Has anyone successfully deployed yet? #343

signalprime opened this issue Jul 18, 2019 · 11 comments

Comments

@signalprime
Copy link

signalprime commented Jul 18, 2019

Hi,

I just start using the starter and it works great, awesome react starter. I've configured everything in firebase.google.com and .env files, following the readme and deployment guide here: https://github.com/kriasoft/react-firebase-starter/wiki/deployment.

But my problem is that when I want to build and deploy, no html files are produced, not even index.html. I've not modified anything except for .env file.

I've logged the details below, anonymizing them with < your site > and < your project > labels.
node: 10.16.0, npm: 6.9.0

  1. react-app build
Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  110.27 KB  public/static/js/12.6d7953a1.chunk.js
  9.56 KB    public/static/js/13.e23a3e23.chunk.js
  7.64 KB    public/static/js/main.cd86c8ac.chunk.js
  5.45 KB    public/static/js/home.9b60061d.chunk.js
  3.3 KB     public/static/js/login.68f29246.chunk.js
  3.13 KB    public/static/js/news.6aa2d53f.chunk.js
  2.04 KB    public/static/js/terms.a6d1de80.chunk.js
  1.29 KB    public/static/js/runtime~main.1786bd33.js
  1.08 KB    public/static/js/privacy.4c391e9d.chunk.js
  984 B      public/static/js/admin.a63c9224.chunk.js
  915 B      public/static/js/user-profile.30e141ac.chunk.js
  803 B      public/static/js/account.1f7da118.chunk.js
  641 B      public/static/js/about.913f482e.chunk.js
  626 B      public/static/js/story.2a8b8363.chunk.js

The project was built assuming it is hosted at <your site>.
You can control this with the homepage field in your package.json.

The build/public folder is ready to be deployed.
You may serve it with a static server:

  yarn global add serve
  serve -s build/public
  1. yarn deploy-prod
    Comments: the app exists with firebase.google.com, not with cloud appengine though
yarn run v1.17.3
$ firebase --project=<your project> deploy && node ./scripts/post-deploy --env=prod

=== Deploying to '<your project>'...

i  deploying storage, functions, hosting

There was an issue deploying your functions. Verify that your project has a Google App Engine instance setup at https://console.cloud.google.com/appengine and try again. If this issue persists, please contact support.

Error: HTTP Error: 404, Could not find Application "<your project>".
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

  1. firebase deploy --only functions
=== Deploying to '<your project>'...

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
i  functions: preparing . directory for uploading...

Error: Error occurred while parsing your function triggers.

SyntaxError: Unexpected token c in JSON at position 0
    at JSON.parse (<anonymous>)
    at Object.<anonymous> (/home/webserver/app/build/server.js:764:92)
    at __webpack_require__ (/home/webserver/app/build/server.js:21:30)
    at /home/webserver/app/build/server.js:85:18
    at Object.<anonymous> (/home/webserver/app/build/server.js:88:10)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
  1. firebase deploy --only hosting
    comments: works fine, it registers and loads images and favicon.ico to the remote firebase server, but no html files are produced inside ./build/public
=== Deploying to '<your project>'...

i  deploying hosting
i  hosting[<your site>]: beginning deploy...
i  hosting[<your site>]: found 46 files in ./build/public
✔  hosting[<your site>]: file upload complete
i  hosting[<your site>]: finalizing version...
✔  hosting[<your site>]: version finalized
i  hosting[<your site>]: releasing new version...
✔  hosting[<your site>]: release complete

✔  Deploy complete!

  1. firebase serve --only hosting
    This produces the same result as deploying to firebase servers,
i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000

  1. firebase serve
=== Serving from '/home/webserver/your_project'...

✔  functions: Using node@10 from host.
i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000
✔  functions: Emulator started at http://localhost:5001
i  functions: Watching "/home/webserver/your_project" for Cloud Functions...
⚠  TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at Object.<anonymous> (/home/webserver/your_project/build/server.js:762:89)
    at __webpack_require__ (/home/webserver/your_project/build/server.js:21:30)
    at /home/webserver/your_project/build/server.js:85:18
    at Object.<anonymous> (/home/webserver/your_project/build/server.js:88:10)
    at Module._compile (internal/modules/cjs/loader.js:776:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
⚠  We were unable to load your functions code. (see above)
   - You may be able to run "npm run build" in your functions directory to resolve this.

@signalprime signalprime changed the title Deploying without index.html? Deployment - index.html not being produced Jul 18, 2019
@signalprime signalprime changed the title Deployment - index.html not being produced Deployment - index.html not necessary? Jul 19, 2019
@koistya
Copy link
Member

koistya commented Jul 19, 2019

@greg234234 it looks like something wrong with the build output. You may want to open the file that Firebase is complaining about inside of the build folder and check what's wrong on that line:

SyntaxError: Unexpected token c in JSON at position 0
    at JSON.parse (<anonymous>)
    at Object.<anonymous> (/home/webserver/app/build/server.js:764:92)
    at __webpack_require__ (/home/webserver/app/build/server.js:21:30)
    at /home/webserver/app/build/server.js:85:18

Can you try yarn relay && yarn build... in case GraphQL fragments were not compiled for some reason.

Note that there should not be index.html in the build output, this is by design. There is Express.js server inside of the src/server folder that is responsible for rendering HTML pages (see src/server/index.js, src/server/app.js, src/server/ssr.js).

@signalprime signalprime changed the title Deployment - index.html not necessary? Deployment - Mild Confusion Jul 19, 2019
@signalprime
Copy link
Author

signalprime commented Jul 19, 2019

@koistya Thanks for your response.

I think it's definitely related to the Firebase Service Key. On that line referenced in the error, we see it complaining about: JSON.parse(process.env.GCP_SERVICE_KEY)

Inside ".env", GCP_SERVICE_KEY and FIREBASE_CONFIG are using the same JSON dictionary from https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk

Forgive me, some follow-up questions. When submitting the information like so:

> firebase --project=example-prod functions:config:set \
>     app.app_origin="https://example.com" \
>     app.gcp_service_key="xxxxx" \
  1. The "app.gcp_service_key" is "private_key_id" from that adminsdk JSON file?
  2. do we really not update .env.production file with the GCP_SERVICE_KEY JSON dictionary?
  3. Unrelated but I never could find where to generate the app.jwt_secret
  4. And finally, do we need to make a node.js app with https://console.cloud.google.com/appengine, or is that just a complaint due to a misconfiguration? In package.json "name": "app" doesn't match the name of my app in the Firebase console.

Sorry for all the questions, thanks for your insights 👍

(yarn relay && yarn build ran without issue but didn't resolve it)

@koistya
Copy link
Member

koistya commented Jul 19, 2019

@greg234234 you can find GCP service key on this page:

image

It's the same key known as Firebase Admin SDK in Firebase Console and it gives you more permissions than default credentials. For example, it allows doing things like firebase.auth().createCustomToken() in your server-side code (src/server/**). There is also a public key that can be used in the front-end code. You can find things that are exposed for use in the client-side code here > src/server/config.js (this file chery-picks environment variables that are safe to use on the client, and injects them into the client-side code (see const config = useConfig() React hook as an example).

You just click [Copy] icon in Google Cloud Console next to the server-side key, then serialize it into a string (e.g. by copying it into browser's console: JSON.stringify(<key>) and copying the stringified output). Then set this key per environment using firebase --project=<project> functions:config:set app.gcp_service_key="..." command. You don't have to put it into .env.production file (normally you want all your secrets set via Firebase (or, Cloud Functions) tooling as opposed to storing that info in the repo.

JWT_SECRET is a random string, you can put any sequence of characters in there, it's used to encode/decode OAuth JWT token during login (see src/server/passport.js).

You do not need to use Google App Engine, the app is supposed to be deployed to Firebase Functiosn (Google Cloud Functions). You can set project.json/name attribute to any string, this doesn't affect anything.

Most likely you would have two (or, more) projects in GCP/Firebase, e.g. example-prod for production, example-test for QA, and optionally example-dev for development needs. You may want to copy DEV (or TEST) GCP service key into the .env file, so it can be used when you run your app locally. And set production GCP key using firebase ... CLI per GCP project.

@koistya
Copy link
Member

koistya commented Jul 19, 2019

@greg234234 BTW, I would be grateful if you would add missing info into the Deployment wiki page after figuring this thing out.

@signalprime
Copy link
Author

signalprime commented Jul 20, 2019

@koistya Yes, I'll be glad to update the Deployment wiki. From which branch do I make the PR?

You just click [Copy] icon in Google Cloud Console next to the server-side key, then serialize it into a string (e.g. by copying it into browser's console: JSON.stringify() and copying the stringified output). Then set this key per environment using firebase --project= functions:config:set app.gcp_service_key="..." command.

Referring to the string from the image you shared, JSON.stringify just adds an extra set of quotes around the string. I've been applying JSON.serialize to both strings, from Service Account key, and the Server Key, without success. So I'm writing to confirm it.

On my credentials page, I have 4 items: the Server key, Browser key (both auto created by firebase), OAuth, and the Service Account key which is another string of the same shape/size belonging to the service account named "firebase-adminsdk".

This brings me to the JSON string for that service account, as shown in the example .env file:

GCP_SERVICE_KEY={"type":"service_account","project_id":"example-dev","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMBPeEoIK6sSqj\nIj30SWCUicZPTzTKJJwfbRHfUlC/E/8S9WNDTqO16vM4SD1jpNH35/ei0pZcrmoP\n9Zk9wViEz9/NgzbDbBHWQzgpJVEvcY+uM8HQ8YvRXQ8eW415x+rmoGrJtVDl37V8\nD7FIrRxEv1PUCzh8/gFm0c2lLr8sUn/r4SaFpuj0mXu5+ZFZFuxjixvjodWx5n3v\n/0/D/uGWPKBNqcuFvXTflIMk+wnrLq91GJypGVVtmXoIWZ4iNVfjfGVcpOtUiilr\nwC/hU5Cn7LYEBHYoOWPnc/TCftePiC/ZwJL56L3Mn9MT3mtGtT0R+sfZKa6oFdfy\nhXJhatwZAgMBAAECggEAOyyboBewIzccv0lAv/iCb0LQxpMaJCFfOQw5GVV2Px2t\nJ5IN8uk9uZeGaQYm7B5TmjxpSowa+ZHLCIr7IfrQ0mC6sJCE00SmncdMZD7DH+gn\nvOadKh3NKHH93xe93psaKj9QCeYxqyLqMCwbBxHSt6voxAFnJnXD8U8b/vOilldo\nXi7JA8nu+oX3ySJzG0n5Ug5zYCS8zrBapxGWDW78orM7zvZ298xraf8ooOwSzj3X\njsNtbvvB/sUNwnnGH9wwDwLNrw5WavkUG26ugaMmzHBzN3YNpjK+eCG8CkJRV1cL\nBdBwDaTAk9DIQyWaw/LAl+Ha2eE9AUt0lABGFeydEwKBgQD43GW7mATLTYHO0xxM\naoTFSpHM/IJNa49THhv6Nv+G1DIBLq1LlrSDncQOsoP0f/jwnLKcwAAg9DoYnnd5\nygoE9Nh8Lgejk2xW9NTyH4M7KlV3sOpV9OOAzE7hXYCVBoyI379Wgs/pqLeGpIwJ\nMIx/Gl4Z8G0AcAupxZKhQuxlOwKBgQDR30JTW93jcHfnhnCATr/F38XnL+agGZy6\n2BR2axeU+Ct2W8hLFUVoylkycqF7yD/QtW/EjZOPF0RKOM6IHiV3dCyJoz534+x4\nA/0e0UyrEdG5g7W+O79bWow+ER5YYl22TgDOmE+UFlBO6fJW9+I0YvTqki+YSwlT\nrwA+MqAeuwKBgQCPXJgWm5qXa80N0rwIoYxfA3g+uHBwHThxz3Sajjhh+bfcyoD2\nfJj9AVPCi8BMh7RnGD4k4s6wLUGSkSeOt39SH6Le1r171B+jcGOEH/c/jEG0M+yr\nG+o7dncyiOTb9OvcpdjaA322w4UGQaCSYq9tQUlYdBK3H9T4NmMkFyOLpQKBgEwD\nmilJF9f971/rQKooW6tWvn5ayiRowmymQNsXNMZfEJbg7W3MeYRX7fCotjZ4NCzq\n2l2NjcmA+toLMzr3+EgIyuzbNJAF/KsHftF/q042uQiBXP1W9Jso86yzVJNcpWaX\nYBFz9zbC0jmS4JSBWevxf5XKdvSpEOq/cs4UVgxrAoGBAJOKGKB8LgsbH9DgTMQs\nByKYONEe64YfKEXDJ1sdYttz3C9EZyGRICYpnEbpBUmMa82aYT7MWinYa2jHY0Py\nyFzi4aS5gRgqF6KFRWfbkkXDupwgS8/KJo56MX2Uie1E7fGc7TCtVRW1n4HE5oxt\ndQpBhaUyp0K8c5U4A+BGdwkK\n-----END PRIVATE KEY-----\n","client_email":"...","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"..."}

Trying to make sense of the JSON error from server.js I wonder, do we JSON.stringify part or all of this JSON for app.gcp_service_key="..."? I'm asking because we see it's looking for JSON format in this error

SyntaxError: Unexpected token M in JSON at position 0
    at JSON.parse (<anonymous>)
    at Object.<anonymous> (/home/webserver/litstudios.reconstruction/build/server.js:764:92)

Where line 764 is
if(!firebase.apps.length){firebase.initializeApp({credential:firebase.credential.cert( JSON.parse(process.env.GCP_SERVICE_KEY))});}if(true){// Server environment

@signalprime
Copy link
Author

signalprime commented Jul 21, 2019

Small update, relating to my last point...
To generate this key

GCP_SERVICE_KEY={"type":"service_account","project_id":"example-dev","private_key_id":"...","private_key":"-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDMBPeEoIK6sSqj\nIj30SWCUicZPTzTKJJwfbRHfUlC/E/8S9WNDTqO16vM4SD1jpNH35/ei0pZcrmoP\n9Zk9wViEz9/NgzbDbBHWQzgpJVEvcY+uM8HQ8YvRXQ8eW415x+rmoGrJtVDl37V8\nD7FIrRxEv1PUCzh8/gFm0c2lLr8sUn/r4SaFpuj0mXu5+ZFZFuxjixvjodWx5n3v\n/0/D/uGWPKBNqcuFvXTflIMk+wnrLq91GJypGVVtmXoIWZ4iNVfjfGVcpOtUiilr\nwC/hU5Cn7LYEBHYoOWPnc/TCftePiC/ZwJL56L3Mn9MT3mtGtT0R+sfZKa6oFdfy\nhXJhatwZAgMBAAECggEAOyyboBewIzccv0lAv/iCb0LQxpMaJCFfOQw5GVV2Px2t\nJ5IN8uk9uZeGaQYm7B5TmjxpSowa+ZHLCIr7IfrQ0mC6sJCE00SmncdMZD7DH+gn\nvOadKh3NKHH93xe93psaKj9QCeYxqyLqMCwbBxHSt6voxAFnJnXD8U8b/vOilldo\nXi7JA8nu+oX3ySJzG0n5Ug5zYCS8zrBapxGWDW78orM7zvZ298xraf8ooOwSzj3X\njsNtbvvB/sUNwnnGH9wwDwLNrw5WavkUG26ugaMmzHBzN3YNpjK+eCG8CkJRV1cL\nBdBwDaTAk9DIQyWaw/LAl+Ha2eE9AUt0lABGFeydEwKBgQD43GW7mATLTYHO0xxM\naoTFSpHM/IJNa49THhv6Nv+G1DIBLq1LlrSDncQOsoP0f/jwnLKcwAAg9DoYnnd5\nygoE9Nh8Lgejk2xW9NTyH4M7KlV3sOpV9OOAzE7hXYCVBoyI379Wgs/pqLeGpIwJ\nMIx/Gl4Z8G0AcAupxZKhQuxlOwKBgQDR30JTW93jcHfnhnCATr/F38XnL+agGZy6\n2BR2axeU+Ct2W8hLFUVoylkycqF7yD/QtW/EjZOPF0RKOM6IHiV3dCyJoz534+x4\nA/0e0UyrEdG5g7W+O79bWow+ER5YYl22TgDOmE+UFlBO6fJW9+I0YvTqki+YSwlT\nrwA+MqAeuwKBgQCPXJgWm5qXa80N0rwIoYxfA3g+uHBwHThxz3Sajjhh+bfcyoD2\nfJj9AVPCi8BMh7RnGD4k4s6wLUGSkSeOt39SH6Le1r171B+jcGOEH/c/jEG0M+yr\nG+o7dncyiOTb9OvcpdjaA322w4UGQaCSYq9tQUlYdBK3H9T4NmMkFyOLpQKBgEwD\nmilJF9f971/rQKooW6tWvn5ayiRowmymQNsXNMZfEJbg7W3MeYRX7fCotjZ4NCzq\n2l2NjcmA+toLMzr3+EgIyuzbNJAF/KsHftF/q042uQiBXP1W9Jso86yzVJNcpWaX\nYBFz9zbC0jmS4JSBWevxf5XKdvSpEOq/cs4UVgxrAoGBAJOKGKB8LgsbH9DgTMQs\nByKYONEe64YfKEXDJ1sdYttz3C9EZyGRICYpnEbpBUmMa82aYT7MWinYa2jHY0Py\nyFzi4aS5gRgqF6KFRWfbkkXDupwgS8/KJo56MX2Uie1E7fGc7TCtVRW1n4HE5oxt\ndQpBhaUyp0K8c5U4A+BGdwkK\n-----END PRIVATE KEY-----\n","client_email":"...","client_id":"...","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_x509_cert_url":"..."}

I went to this page https://console.firebase.google.com/project/_/settings/serviceaccounts/adminsdk and clicked "Generate new private key", saved it, and ran JSON.stringifiy on it. Feeding that to app.gcp_service_key in firebase config:set returns the following error:
Error: HTTP Error: 400, Precondition check failed.

@signalprime
Copy link
Author

signalprime commented Jul 22, 2019

@koistya please could you confirm, you mentioned using the server-side key for the app.gcp_service_key field in the firebase configuration command. The server-side key isn't a JSON object needing to be stringified, I've tried to come forward with the best guess, and that configuration comes with another error.

@signalprime signalprime changed the title Deployment - Mild Confusion Has anyone successfully deployed? Jul 23, 2019
@signalprime signalprime changed the title Has anyone successfully deployed? Has anyone successfully deployed yet? Jul 23, 2019
@signalprime
Copy link
Author

signalprime commented Jul 23, 2019

Trying to debug this line 764 in './app/build/server.js

if(true){const _functions$config=functions.config(),config=_functions$config.app;Object.keys(config).forEach(key=>{process.env[key.toUpperCase()]=typeof config[key]==='object'?JSON.stringify(config[key]):config[key];});};dotenv.config({path:`.env.production`});dotenv.config({path:'.env.local'});dotenv.config({path:'.env'});// Configure Firebase Admin SDK

I've added this line console.log({credential:firebase.credential.cert(JSON.parse(process.env.GCP_SERVICE_KEY))}); and until now, anything I have used for GCP_SERVICE_KEY shows me the following error:

SyntaxError: Unexpected token t in JSON at position 1

This is because I have "t" for "type" starting the JSON, as we see in the examples GCP_SERVICE_KEY={"type":"service_account"

So what are they expecting for position 1 of that JSON?

@koistya
Copy link
Member

koistya commented Jul 31, 2019

@greg234234 you may need to check what has been written to Firebase env by running:

$ firebase --project=<PROJECT> functions:config:get

It should return something like this:

{
  "app": {
    "gcp_service_key": {
      "client_email": "firebase-adminsdk-xxx@holahelp-test.iam.gserviceaccount.com",
      "type": "service_account",
      "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fo1ka%40holahelp-test.iam.gserviceaccount.com",
      "client_id": "xxx",
      "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
      "auth_uri": "https://accounts.google.com/o/oauth2/auth",
      "private_key": "-----BEGIN PRIVATE KEY-----\nxxx\n-----END PRIVATE KEY-----\n",
      "token_uri": "https://oauth2.googleapis.com/token",
      "private_key_id": "xxx",
      "project_id": "xxx"
    },
    "firebase_auth_domain": "xxx.com",
    "gcp_browser_key": "xxx",
    "pgdatabase": "xxx",
    "gcp_server_key": "xxx",
    "app_env": "production",
    "app_origin": "https://xxx.com"
  }
}

You can update app.gsp_service_key environment variable by inserting JSON string enclosed in single quotes:

$ firebase --project=<PROJECT> functions:config:set \
   app.gcp_service_key='{"type":"...",...}'

@janat08
Copy link

janat08 commented Feb 24, 2021

A full tutorial on handling variables or at least helpful links would be useful. I for some reason couldn't add firebase to created google project, so had to restart with a new one created through firebase console (I blame adding admin service key).

@jaaimino
Copy link

In case anyone is still having this issue I figured it out. Check out this documentation page:
https://firebase.google.com/docs/reference/admin/node/admin.credential

What I did was just split up the admin key into 3 ENV variables.
GCP_CLIENT_EMAIL=
GCP_PRIVATE_KEY=
GCP_PROJECT=
And they can be passed in this way instead in server/indexjs
if (!firebase.apps.length) { firebase.initializeApp({ credential: firebase.credential.cert({ projectId: process.env.GCP_PROJECT, privateKey: process.env.GCP_PRIVATE_KEY, clientEmail: process.env.GCP_CLIENT_EMAIL }), }); }
For some reason it's having a hard time parsing the entire key as json but splitting it into a few ENV variables worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants