Hi I am running firebase node project locally with Firestore, Functions and Auth emulators. When I try signing in with popup I get an empty popup with no dummy login. Please find image and code below. I don't understand with there is no dummy data. Works perfectly fine when connecting to production environment. Please can anyone explain why I don't see any accounts?
// Get a Firestore instance
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const functions = getFunctions(app);
export const db = getFirestore(app);
if (process.env.NODE_ENV === "development") {
connectAuthEmulator(auth, "http://localhost:9099/");
connectFunctionsEmulator(functions, "localhost", 5001);
}
Clicking on add new account does nothing.
Node service
you might be doing something wrong here
would recommend going through this article and hope you find a work around.
https://firebase.google.com/docs/emulator-suite/connect_auth
Your question is ambiguous. What accounts are you expecting to see in that popin? If you want to see the accounts you created using the SDK (client or admin), you need to go to the emulator UI, available by default on localhost:4000 and then check the Auth tab.
The popin in your screenie is only there to generate federated accounts.
Related
I want to test my firebase back-end involving firestore, auth, and functions. There are cloud functions on new user created or deleted and rest like apis all affecting firestore data.
I want to run test like this.
I will start firebase emulator (with no data) in a terminal.
Run test file. Following everything will be in a script, so no part is manual.
I will register new users. Those should trigger firebase functions lets say affecting users collection.
Test if the users collection is affected.
Then do a fake login with any created user say Jake Williams.
Call some rest api. Those api will again change firestore data. For these cloud functions auth received will be of Jake Williams
Test if those firestore data is affected.
Clean emulator data and run other tests.
I have gone through docs, yet these is unclear. Went through github/quickStart-testing, still no help. I see there are tutorial which test firestore rules and some test cloud functions separately.
Can I setup a test project to work like my above requirements?
I find Firebase guide confusing. There they mentioned firebase emulators:exec "./my-test.sh", not sure my-test.sh is. Normally not seen .sh file in node.js testing workflow. After 2-3 days, found the proper solution to my own question.
Here are some things you should know.
firebase emulators:exec
firebase emulators:exec 'npm run test' command run your test files within firebase emulator. So when your test files are using firebase admin import * as admin from "firebase-admin"; I think this firebase admin will be linked to that emulator instance being created. Running admin.auth().createUser(...) in that test file, then user will be created on that emulator. This createUser will also trigger side effects in cloud functions. You just have to wait for 5 sec before testing triggered functions effects.
You need to init admin and firebase function test with your project id
import functionTest from 'firebase-functions-test'
import * as admin from "firebase-admin";
const PROJECT_ID = "your project id"
const test = functionTest({
projectId: PROJECT_ID,
});
admin.initializeApp({
projectId: PROJECT_ID,
})
If you want to clear emulator data and reinit app between each tests
import axios from 'axios'
import * as admin from "firebase-admin";
const PROJECT_ID = "your project id"
const deletingFirebaseDataUrl: string = `http://127.0.0.1:8080/emulator/v1/projects/${PROJECT_ID}/databases/(default)/documents`;
const deletingAuthDataUrl: string = `http://localhost:9099/emulator/v1/projects/${PROJECT_ID}/accounts`;
async function initApps() {
admin.initializeApp({
projectId: PROJECT_ID,
})
}
async function deleteAllDataAndApps() {
admin.apps.forEach(app => app?.delete());
await axios.delete(deletingFirebaseDataUrl) //
await axios.delete(deletingAuthDataUrl)
test.cleanup();
}
beforeEach(initApps)
afterEach(deleteAllDataAndApps)
Going through the docs, I did not find these things or they were not clear to me.
I would like to test the Google Cloud Speech-to-Text API from within Firebase Emulators. I currently have a trigger set on Firebase Storage that automatically gets fired when I upload a file via the Emulator Storage UI. This makes a request to the Speech to Text API, but I keep getting a permission denied error, as follows:
Error: 7 PERMISSION_DENIED: Cloud Speech-to-Text API has not been used in project 563584335869 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/speech.googleapis.com/overview?project=563584335869 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
I understand that project 563584335869 is the Firebase Cli project.
I have set the following environment variables when starting the emulator:
export GCLOUD_PROJECT=my-actual-glcloud-project-id && export FIREBASE_AUTH_EMULATOR_HOST='localhost:9099' && export GOOGLE_APPLICATION_CREDENTIALS=./path/to/service-account.json &&
firebase emulators:start
The service_account.json key file is associated with a service_account that has the following roles, as demonstrated by running
gcloud projects get-iam-policy my_project_id --flatten="bindings[].members" --format='table(bindings.role)' --filter="bindings.members:serviceAccount:my_service_account#my_project_id.iam.gserviceaccount.com"
ROLE
roles/speech.admin
roles/storage.admin
roles/storage.objectAdmin
roles/storage.objectCreator
roles/storage.objectViewer
Since the credentials for the service account I am using should have admin access to the speech to text api, why do I keep getting a permission denied error when running from the emulator, and how can I fix it?
The project id 563584335869 is not yours. It is firebase-cli cloud project’s project-id. In this case, the problem is arising because you have to set your own configuration using your credentials or your key.
You can see below a code for NodeJS which I found in github[1] where it shows how to configure your authentication to use the API.
// Imports the Google Cloud client library
const textToSpeech = require('#google-cloud/text-to-speech');
// Create the auth config
const config = {
projectId: 'grape-spaceship-123',
keyFilename: '/path/to/keyfile.json'
};
// Creates a client
const client = new textToSpeech.TextToSpeechClient(config);
[1]https://github.com/googleapis/nodejs-text-to-speech/issues/26
EDIT
There are different ways to set up your authentication for speech to text. One way to resolve this problem would be to add the same auth configuration as the Text-to-Speech and it should look something like this in your code.
// Imports the Google Cloud client library
const speech = require('#google-cloud/speech');
// Create the auth config
const authconfig = {
projectId: 'grape-spaceship-123',
keyFilename: '/path/to/keyfile.json'
};
// Creates a client
const client = new speech.SpeechClient(authconfig);
Another way to solve this problem according to this Google Cloud Documentation[2] is to setup your authentication.
[2]https://cloud.google.com/speech-to-text/docs/libraries#setting_up_authentication
Firebase is great, it helps in so many ways, and well-integrated with crashalytics, Google Analytics, Google Tag Manager, you name it.
We are building a mobile SDK, however, it seems that you can only link to Firebase on the app level (you can't initialise your own SDK to send to a different account than App's Firebase account).
Is there a workaround to allow me as an SDK developer to collect events, crash reports,.... to a Firebase account related to the SDK alone, regardless to the app that is using the SDK?
Many thanks
You can initialize more than one instance of the SDK at once. However, you should make consumers of your SDK aware that it is doing so and they should have a clear way to opt-out.
When an application is launched, the FirebaseInitProvider will handle initialization of the default application instance. This default app instance has a name of "[DEFAULT]".
If you wanted to have a second user logged in, make use of a separate project, make use of a secondary database, and so on - you can just initialize another application instance. Importantly (taken from the docs), any FirebaseApp initialization must occur only in the main process of the app. Use of Firebase in processes other than the main process is not supported and will likely cause problems related to resource contention.
This is done using FirebaseApp.initializeApp() like so:
FirebaseApp nameApp = FirebaseApp.initializeApp(context, config, "name");
To replicate the default instance so you can have more than one user logged in, you can use:
FirebaseApp defaultApp = FirebaseApp.getInstance();
FirebaseApp secondaryApp = FirebaseApp.initializeApp(
defaultApp.getApplicationContext(),
defaultApp.getOptions(),
"secondary"
);
To use a separate instance entirely, you load your configuration into a FirebaseOptions object using:
FirebaseOptions sdkAppOptions = new FirebaseOptions.Builder()
.setApiKey(sdkApiKey)
.setApplicationId(sdkAppId)
.setDatabaseUrl(sdkDatabaseUrl)
.setGcmSenderId(sdkGcmSenderId)
.setProjectId(sdkProjectId)
.setStorageBucket(sdkStorageBucket)
.build();
FirebaseApp sdkApp = FirebaseApp.initializeApp(
sdkContext,
sdkAppOptions,
"com-example-mysdkproject" // <- use namespace as best practice
);
Once you have an instance of FirebaseApp, you can then pass it through to other the other services using:
FirebaseAuth sdkAuth = FirebaseAuth.getInstance(sdkApp);
// or
FirebaseApp sdkApp = FirebaseApp.getInstance("com-example-mysdkproject");
FirebaseAuth sdkAuth = FirebaseAuth.getInstance();
I'm learning GCP and in their Firestore, I'm confused with the difference of Admin.firestore & Firebase.firestore.
this is the code for admin:
const admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://<firestoreprojectnameurl>"
const db = admin.firestore();
});
while this is the code for the firestore
const { config } = require('./config');
const firebase = require("firebase");
firebase.initializeApp(config);
const db = firebase.firestore();
Please note that only 1 db at a time will work and for my current set-up I use the db = firebase.firestore() although if I change it to db = admin.firestore ite works fine and all my code works the same.
Thank you in advance!
The JavaScript SDK for web clients (your second example) is different than the JavaScript SDK for nodejs backends (your first example). They have different APIs, though they might appear very similar for most types of queries. But they are definitely not interchangeable. You are supposed to pick the one that matches the environment where it's going to be used. The Firebase Admin SDK is definitely not usable in web clients, though the web client SDK might work in nodejs backend environments (but I don't recommend it).
It might also help to know that the Firebase Admin SDK is actually just a wrapper around the Google Cloud nodejs SDK. You can compare the API documentation of the web SDK to the nodejs SDK if you want to take a closer look.
I have the following setup: Vue Webapp with Hosting, Cloud Functions and Firestore.
When deploying the app to the Google Cloud, everything works. When i emulate the functions and hosting using firebase emulators:start --only functions,hosting, I can use the hosted app and cloud functions, but the authentication information from context.auth is undefined.
This works in the cloud but not in the emulator. Any ideas or solutions?
Note: I also set the admin credentials as described in the Docs.
Edit: I have a colleague that runs the emulator on windows successfully including authentication info, but I can't find any differences in the setup?!
export default class AuthGuard {
private readonly authentication: object;
public constructor(context: any) {
this.authentication = context.auth;
}
public isAuthenticated(): boolean {
console.log('this.authentication', this.authentication ); // this in undefined
if (this.authentication === undefined) {
throw new functions.https.HttpsError(
'unauthenticated',
'The request requires user authentication',
);
}
return true;
}
[Firebaser here] This is a bug in the emulators and it was fixed in version 7.16.2:
https://github.com/firebase/firebase-tools/releases/tag/v7.16.2
To update, just re-install the Firebase CLI at the latest version.
As mentioned in the official documentation Set up admin credentials in Emulator, this is an optional setting that you need to configure, in case you want to test your authentication as well.
To set up the authentication, please, follow the below steps.
Open the Service Accounts pane of the Google Cloud Console.
Make sure that App Engine default service account is selected, and use the options menu at right to select Create key.
When prompted, select JSON for the key type, and click Create.
Set your Google default credentials to point to the downloaded key:
As per the documentation indicates, this should be good for testing, since now it will be using the Admin SDK for tests. One of the examples mentioned is calling the function admin.auth().getUserByEmail(email).
Besides that, in this other below case - now from a Github issue - you can get more examples and information on how to use authentication in local emulator.
Add firebase authentication emulator to emulator suite
I would like to add as well, that as per the official documentation indicates, the Local Emulator is in Beta. So, it might be worth it to contact the Firebase support team directly, via their free support.
Let me know if the information helped you!