I am using Stripe in an app with Firebase Functions.
I store the Stripe keys in the Firebase environment via the following:
firebase functions:config:set
All works in Test mode.
Now I would like to enable Stripe in Production mode.
I replaced my Stripe keys to use the Production "live" keys.
I verified the new variables are set using the following:
firebase functions:config:get
I see that the "public_key" and "secret_key" values have the Production values, "pk_live....." and "sk_live.....", respectively.
I deployed the Firebase functions again, after setting the new environment values.
But, when using Stripe in my app, it still shows "Test Mode".
Any assistance will be appreciated.
Below is a screenshot of the Stripe dialog where it indicates "Test mode".
I reviewed the cloud functions in Google Cloud and they have the correct keys:
Related
I am having trouble running the firebase functions emulator towards a production database. I have a project which is not publicly released yet so I can run towards production with any negative effects.
My project uses only the realtime database, it does not use Firestore (so other questions on SO are not relevant) The documentation states "Cloud Firestore and Realtime Database triggers already have sufficient credentials, and do not require additional setup." so according to that, I shouldn't need any additional setup in order to point to the production database.
According to all of the documentation on Firebase, the project should run towards the real firebase database if I only start the functions emulator and do not start the database emulator. This warning seems to say so, too:
functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, firestore, database, hosting, pubsub
However, this is not what happens. Instead, I get the following error:
functions[onGlobalClientRequest]: function ignored because the database emulator does not exist or is not running.
I have read the firebase documentation and nothing is really mentioned other than setting credentials should not be needed (but I am setting credentials anyway using export GOOGLE_APPLICATION_CREDENTIALS="/path/to/credentials.json" before running the functions emulator.)
onGlobalClientRequest looks like this:
export const onGlobalClientRequest = functions.database
.ref( client_requests_key + "/{pushedid}")
.onCreate(
async (
snap: functions.database.DataSnapshot,
context: functions.EventContext,
) => {
///.... code here...
},
);
The locally emulated Firebase Functions will be able to write to the Prod database, but will not be able to get triggered by the production database.
Here is a SO answer from a Google employee that states the aforementioned.
Also, quoting from this other SO answer from another Google employee:
In general the rule with emulators:start is that we comprehensively emulate whatever is running. So for example if you're running the Functions and Database emulator, all writes from functions (through admin.database().... will be redirected to the Database emulator. But writes to Firestore (admin.firestore()...) will try and hit production because that emulator is not running.
Operations on a Realtime Database (RTDB) trigger the functions in the corresponding project. So the production RTDB triggers functions of your production project, and the emulated RTDB triggers emulated functions.
If you want to test functions triggered by RTDB operations locally with the emulator, you have to use the RTDB emulator as well. This is explained in the doc here.
If you only want to test HTTP callable functions, then you can use a remote RTDB.
I am running scripts to interact with Firestore (e.g. creating a doc). I've provided a service account key file to do so (tried with key files from Firebase and GCloud) - scripts run the same.
I am aware that Firebase is now built / closely linked to GCloud so I am expecting the key files to be similar.
However, the docs recommend initializing the sdk with a key from Firebase console when adding Firebase admin to your server and from GCloud Console for unit testing.
So here are my questions:
Why recommend 2 different ways to generate them? Is one more appropriate than the other?
Do service account key files generated in Firebase (1) and GCloud (2) consoles differ in terms of scope? Do they allow the same operations? Are they granted equivalent permissions?
Firebase Console > Project Settings > Service Accounts > Firebase Admin SDK > Create new private key
https://console.firebase.google.com/project/[my-project-id]/settings/serviceaccounts/adminsdk
Google Cloud Console > IAM & Admin > Service Accounts > App Engine default service account > Create key
https://console.cloud.google.com/iam-admin/serviceaccounts?project=[my-project-id]
The service account and credentials provided by the Firebase console are no different than one that you'd create in the Cloud console. Firebase is just making it easier to get started, so you don't have to learn the Cloud console. If you want to use the one provided by Firebase, fine. If you want to use one you create and configure in the Cloud console, fine. The Firebase service account should be visible in the Cloud console just like any other. When it comes to assigning permissions to individual products, you can still choose either one to work with. It's up to you.
I am working on small project where data is uploaded to Firestore on one page, and retrieved on another in the same website. Is it possible to test the Firestore integration when the website is hosted on localhost?
When I try accessing the Firestore functionality after deploying my website on localhost, I get:
"google.api_core.exceptions.FailedPrecondition: 400 The Cloud Firestore API is not available for Datastore Mode projects." error.
The only documentation I can find is: "How to deploy Flask Crud API with Firestore..."
Note:
1. I looked at the error, and double checked that my project is in Firestore mode (I created the project from Firebase Console), and then used following in my Flask application to authenticate database:
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate("path/to/serviceAccountKey.json")
firebase_admin.initialize_app(cred)
Any other inputs on this would be appreciated!
I tried looking into Simulators, but most of the documentation said that it's only for Cloud functions, whereas I'm trying to test simple operations.
Thank you for looking into this.
The error message means that your Cloud Firestore database is in Datastore mode instead of Native mode. Unless you never saved anything to your database, you can't change the mode.
Try creating a new project, creating a new Cloud Firestore database, and selecting Native mode:
In the GCP console, it'll ask you to choose.
In the Firebase console, it'll automatically select Native mode.
I found out the issue. I was using cred = credentials.Certificate("path/to/serviceAccountKey.json") code with new generated private key for authenticating my firestore database, however, system was taking an old $GOOGLE_APPLICATIONS_CREDENTIALS for this purpose.
Updating that to new key fixed the issue, and yes, I am able to test FLASK app integration with Firestore on Localhost :)
export GOOGLE_APPLICATION_CREDENTIALS='/Users/..../newkey.json'
I am always grateful for your help.
I want to write code admin.initializeApp(); both locally and in production.
When I deploy functions to production with no auguments, it works.
But locally, it requires me to write it like below:
const serviceAccount = require("/home/yhirochick/development/ServiceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://xxxx.firebaseio.com/"
});
In the official documentation it says that configuration is applied automatically when you initialize the Firebase Admin SDK with no arguments
But when I execute the command firebase serve --only functions locally and some calls some requests by postman produce the error below:
[2019-07-22T06:45:26.227Z] #firebase/database: FIREBASE WARNING: Provided
authentication credentials for the app named "[DEFAULT]" are invalid. This
usually indicates your app was not initialized correctly. Make sure the
"credential" property provided to initializeApp() is authorized to access the
specified "databaseURL" and is from the correct project.
I want to know How can I "admin.initializeApp();" no arguments locally.
I have grappled with this also and I don't think the local testing scenario currently is explained very well in the official documentation. But here is a solution:
For your local environment you need to download the firebase projects firebase service account json file (found in firebase console under project settings -> service account) and set an environment variable GOOGLE_APPLICATION_CREDENTIALS to point to the file:
# Linux/MACOS version
export GOOGLE_APPLICATION_CREDENTIALS="[PATH_TO_YOUR_SERVICE_ACCOUNT_FILE]"
Read more here, also on how to do this on Windows
Now you will be able to use admin.initializeApp() (with no arguments) locally.
A possible downside of this approach is that you have to set the environment variable each time you fire up a terminal before you start the firebase emulator, because the variable gets deleted when you end the session.
Automate it...
You could automate the export ... command by bundling it together with the command that fires up the emulator. You could do this by adding an entry to the scripts section of your package.json, e.g.:
"local": "export GOOGLE_APPLICATION_CREDENTIALS='[PATH_TO_YOUR_SERVICE_ACCOUNT_FILE]' && firebase emulators:start --only functions"
Then, in this example, you would only need to type npm run local.
Alternative: provide explicit credentials in local environment only
Look at this example: https://stackoverflow.com/a/47517466/1269280.
It basically use a runtime node environment variable to separate between local and production and then use the explicit way of providing credentials in the local environment only.
This is my preferred way of doing things, as I think it is more portable. It allows me to put the service account file inside my codebase and not deal with its absolute file path.
If you do something like this then remember to to exclude the service account file from your repo! (it contains sensitive info).
Background: difference between production and local service account discovery
The reason that admin.initializeApp() (with no arguments) works out-of-the-box in production is that when you deploy to production, i.e. Firebase Functions, the code ends up in a 'Google managed environment'. In Google managed environments like Cloud Functions, Cloud Run, App Engine.. etc, the admin SDK has access to your applications default service account (the one you downloaded above) and will use that when no credentials are specified.
This is part of Google Clouds Application Default Credentials (ADC) strategy which also applies to firebase functions.
Now, your local environment is not a 'google managed environment' so it doesn't have access to the default service account credentials. To google cloud, your local box is just an external server trying to access your private Firebase ressources. So you need to provide your service account credentials in one of the ways described above.
Before I knew this, I thought that because I was already logged in to firebase via my terminal i.e. firebase login and were able to deploy code to firebase, the firebase emulator would also have the necessary credentials for the firebase admin sdk, but this is not the case.
My Firebase project uses several different storage buckets used by cloud function storage triggers. Although I can change the default bucket for a particular cloud storage function in the console or using CLI after deploying it, I was wondering if there was a way to configure these settings (bucket, memory limit, zip-deployment location) in firebase.json and pick them up automatically during deploy. Sometimes deployment of the entire project resets the cloud function settings, which causes issues for our users. Thanks!
If you want to configure values to consume in your functions, use environment configuration.
From the CLI:
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
Then in a function:
functions.config().someservice.key