firebase `signInWithEmailAndPassword` undefined - firebase

I'm a little new to firebase/cloud functions so forgive if I'm missing something simple.
I'm frustrated now because what I see on the documentation is not working. I read this part of the documentation: signInWithEmailAndPassword but when I use it in my nodejs code that I deploy to Firebase Cloud functions I get the error:
TypeError: auth.signInWithEmailAndPassword is not a function
Note that auth is actually auth(), I just decided to store the result of auth() in the variable auth, so don't let it confuse you.
I looked at the documentation and I don't see anything wrong I'm doing. This post Firebase Auth On The Server With Node.JS / Express and got this for it
If you initialize the Node.js SDK with an API key instead of a service account, you can use the normal client-side auth methods like authWithEmailAndPassword()
Currently I initialize it like this:
admin.initializeApp(functions.config().firebase)
What exactly am I expected to change so that the signInWithEmailAndPassword method becomes available on the object?
Do I really need to get a API key and initialize it like I'm initializing a frontend project when I'm using firebase-admin on a nodejs server?

Cloud Functions run on a trusted environment, and is using the Firebase Admin SDK to access Firebase services. There is no way (nor usually a need) to sign in as a user with email+password using the Admin SDK.
The Firebase Admin SDK runs with administrative privileges, giving it already has full access to the entire Firebase project that the code runs in.

Related

How to Fix Permission Issues in Firebase Cloud Functions (Nextjs Experimental Hosting)

I have an issue related to Firestore, Hosting, and Cloud functions. I deployed a Nextjs application using the just-released experimental web framework support. I'm using Nextjs's Image API, and as expected, the Firebase CLI creates a cloud function for the project. Everything works fine at the start, but when I try to open a page in the application that reads some data from Firestore, it redirects to an auth page, which is unexpected.
Even when I auth with my Google account (since that's the logged-in user to the application), it returns a forbidden error and logs me out.
When I go back and try again, it returns a different error (most likely because I was logged out automatically).
I tried doing some research, and some people suggested adding an allUsers principal permission to Cloud functions, but that didn't work (Error: Principals of type allUsers and allAuthenticatedUsers cannot be added to this resource), and that's even insecure permission. Only authenticated users should be able to read data from the page as already configured in my Firestore security rules. So it's unclear what I need to do since Firebase created the Cloud function automatically or if this is related to my security rules and cloud functions.
What could be wrong? Everything works fine in my existing deployment setup to Netlify (where Edge functions are created automatically using their Nextjs plugin). I'm only trying to test the new Firebase web framework hosting features. Please let me know if you'd need me to provide some more context or debug files to better help you help me.
Thank you!
The message “ App requesting permission to access your google account “ pops up if the function runs in any region other than us-central1.
Currently, Firebase Hosting does not support Cloud Functions in any other regions, Except us-central1.
You can refer to this StackOverflow thread.

Can you use Unity / Firebase Auth with C# google cloud functions?

I'm looking into porting a unity game with a dotnet backend over to firebase firestore / functions, etc. My initial tests look promising, but my biggest hold-up is that I would need to rewrite a lot of the server-side logic in JavaScript.
I know that firebase's functions and firestore both run on google cloud, and the cloud version of functions supports a number of additional languages, including c#. I was able to create a couple of C# test functions and upload them to the same project as my unity test. They show up in the firebase portal and can be called via the HTTP endpoints supplied by google cloud, etc.
I discovered that I can call the function that does not require auth using the FirebaseFunctions callabale API in unity (fun fact, it only seems to work if the response is a JSON object in the form of { "result": [data here] }) I cannot, however, call the version of the same function that does require authentication - it returns an internal error message.
I am wondering there is a way to make these methods callable from the unity firebase API - passing in the user id/auth that I get from logging into firebase? I've seen some examples/answers where people say to call the cloud function directly using the Authorization: bearer token header, but I cannot seem to find a way to get the auth token from the current user in the Unity Firebase API.
I imagine that I am stepping further outside the realm of firebase unity API and more into google cloud/identity platform
You can retrieve the ID token of the current user by calling TokenAsync() on their profile.
That's the value you need to pass along in the Authorization header of the call to Cloud Functions, where you can then access it in you Callable Cloud Function.
Alternatively you can implement a regular HTTP Cloud Function, pass the same in whatever way you see fit there, and then on the server decode and verify the ID token with the Admin SDK yourself.

Isn't it a bad idea to store your service account key in the code? Firestore documentation is saying I should [duplicate]

This question already has answers here:
Is it safe to expose Firebase apiKey to the public?
(10 answers)
Closed 1 year ago.
It is very likely the case I am misunderstanding how all of this works as I am still a newer programmer, but in every course I have taken I have been told not to expose any credentials within the code.
In this Firestore documentation, it tells you to store your service account's credentials as a JSON file and include the file in the directory for the SDK to access. Am I wrong in thinking this is a security issue?
Firestore Getting Started Documentation
Under Initializing Firestore
To use the Firebase Admin SDK on your own server (or any other Node.js environment), use a service account. Go to IAM & admin > Service accounts in the Cloud Platform Console. Generate a new private key and save the JSON file. Then use the file to initialize the SDK:
const serviceAccount = require('./path/to/serviceAccountKey.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount)
});
const db = admin.firestore();
Am I missing something here? Why is it okay to do this?
In fact it depends how we interpret "not to expose any credentials within the code."
Firstly, a main important rule, is to never include secrets (password, or service account keys, or any other confidential data) into the source code, and especially in source code configuration (git / github).
Secondly, in some situation, the only solution to authenticate to a service or API is to use a service account key. In this case, we must keep this file separated from source code, and provide it to app by an environment variable pointing to it.
If your code is running on Google Cloud Platform (App Engine, Cloud Functions, Cloud Run, Firebase Functions...), you can use default authentication provided directly by GCP, and avoid any service account key.
Check Firebase documentation.
In this case, you keep it just for development purpose on your local machine.

Unable to call Firebase function from React.js application

I have a React.js application powered by a number of Firebase functions and real time database standing behind them. It has been working without any issue for the past 2-3 months and now I am getting a warning on the functions logs which says that:
#firebase/database: FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"Failed to parse access token response: Error: Server responded with status 404.\"."}
The way I initialize firebase from my React.js application looks like this:
I have double-checked everything standing behind process.env and it seems to be as expected. The website written in React.js in hosted under the Firebase hosting.
And this is how Firebase functions connect to Admin SDK:
I am not sure what would be the issue here. Nothing has changes in the code base from our side. Not sure if Firebase changed something internally that we need to consider.
What solved the issue for me was to go to the google cloud console (where Firebase functions are also available). Then I opened one of the failing cloud functions and I navigated to
My_Function_Name/Edit/RUNTIME, BUILD AND CONNECTIONS SETTINGS/RUNTIME SERVICE ACCOUNT/
And then I noticed there that for all of my functions it was selected App Engine Default Service Account instead of Firebase Admin SDK. I never explicitly set the runtime to this option. So, when I brought it back to Firebase Admin SDK the error was gone I was able to use the application once again.

How can I "admin.initializeApp();" no arguments in local

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.

Resources