Google App Engine from project A cannot use Firebase Cloud Messaging from project B - firebase

We are running 2 separate Google Cloud Projects, Project A and Project B.
Project A is currently running an App Engine (AE) based API.
The API on project A needs to access the Firebase features on project B.
✅ I have setup cross projects access between the two projects using IAM and most functions are working fine.
App Engine on project A is able to access the Firebase real time db (RTDB) and Firebase Auth functions on Project B.
But we are unable to connect to Firebase Cloud Messaging on Project B
As far as I can see tracing through the Firebase admin SDK calls, we are able to obtain access tokens, and they're all valid as we can use some of the services (i.e. RTDB, Auth)
However, when we try using Firebase Cloud messaging we receive the following error: An error occurred when trying to authenticate to the FCM servers. Make sure the credential used to authenticate this SDK has the proper permissions.
Which seems to originate from a 401 unauthorized response to this service https://iid.googleapis.com/iid/v1:batchAdd
It doesn't seem to matter what amount of Roles on Project B I throw at the Project A service account.
If I use a separate Firebase service account that originated from Project B and use that json file as a credential then the issue go away, but I don't want to distribute credential files around, and everything else work fine without, except FCM.
FWIW this is how i initialise the firebase admin sdk
const firebaseAdmin = require('firebase-admin');
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.applicationDefault(),
projectId:'project-b',
databaseURL: "https://project-b.firebaseio.com",
});
I've also tried setting the serviceAccountId option to the project B service account email that works when manually loaded, but that doesn't change anything (also added Service Account Token Creator role)
The services account has also been given all the permissions listed here https://firebase.google.com/docs/projects/iam/permissions#messaging
Feels like there's a simple connection missing (either a role, or API setting) but I've ran out of idea.
Has anyone done this before and can provide some guidance?
EDIT [CORRECTED IN EDIT 3] I've also tried to manually create a service account on Project B with the same working roles as the Firebase service account that works and i'm getting the same issue (even though it was created on Project B). So sounds like maybe it's not a role issue, nor a cross-project issue?
EDIT 2 I'm on Node Js with latest firebase admin sdk
EDIT 3 Ignore the first edit, i hadn't configured the custom service account correctly, works fine with a service account created from scratch in Project B. So back to cross-project issue then I guess..

So in the case of Real time database, you only need to give Firebase Realtime Database Admin role to the Project A's App Engine service account on Project B.
In Firebase Cloud Messaging you can give Firebase Cloud Messaging Admin role on Project B AND the cloudmessaging.messages.create permission to the service account on Project A.
This will go around the initial 401 unauthorised response from messaging calls.
However, this will still result in an error, this time NOT FOUND, which indicates that the subscription token was not found.
It seems that calls to FCM don't use the projectId setting in firebase admin initialisation and always execute against the project the service account was created in (Project A in this case).
I haven't been able to find a way for FCM calls to executed in the specified projectId scope from another project.

Related

How to access a Firebase project

An app developer has written some code for me that is hosted on Firebase. I want access to the code and so they have apparently given me admin access.
It's a simple question, but I can't figure out how to access the project. I log into the console:
I see how to "create a project", but I don't know how I can access an existing project. I'm assuming thinking about this whole thing in the wrong way somehow. I would appreciate any help.
You typically have two types of administrators in an app built on Firebase:
Project/Firebase administrators who access the project in the Firebase console, and can access the backend view of the services there. This is typically used by the developers on the project, and early administrators. To access the Firebase console, you will sign in with a Google account on console.firebase.google.com.
Application administrators, who use a custom-built interface to manage typical application operations, such as giving roles to users, upgrading accounts, etc. For this type of functionality, you will sign in to the custom built application with a Firebase Authentication account.
The email you got came from Firebase Authentication for an account that was created inside the project. There is no way for this account to be a Firebase administrator or even collaborator on the project, so it was more likely meant as an application administrator. This means that any functionality this allows you to access will have to have been built as part of the app itself, and not in the Firebase console.
updaterequest(messagemap) async {
await FirebaseFirestore.instance
.collection("mentor")
.doc("request")
.update(messagemap)
.catchError((e) {
print(e.toString());
});
}
This is a code used to update some value in your firebase collections. You can use get instead of update to retrieve data from firebase collection. There is also some function like add,remove,set it can be used instead of update command.

firebase firestore gives error for a project that's been added to firebase projects

I've added my project to firestore and I'm doing firestore google auth just fine.
My problem is firebase firestore.
It just doesn't work and I have no idea why.
I'm trying to do a simple add before doing the actual process for my app and it doesn't work.
here I implemented a simple function to add a user and then called it, doing it all in build function.
I get this in my console:
p.s.
"adding user" is printed on console.
p.s.
I do have the firebase_options.dart file.
These thing are you sure that the correct:
1.Using correct google_services.json file
2.Edit Fire store rules if you are not using authorization
You have to manually whitelist your existing Google OAuth 2.0 client IDs in the Firebase console before using it with the new Auth APIs.
In order to do so, follow these steps:
Go to the Credentials section in the Google API Console.
Select from the top right corner the project where you had previously configured Google Sign-In.
Go to the OAuth 2.0 client IDs section
If you are using Google Sign-In on Android or iOS applications:
Take note of the Client ID string corresponding to all the entries registered for your applications.
Input these Client IDs into your Firebase project’s configuration:
Go to the Firebase console at https://console.firebase.google.com
Open the Auth section
Under Sign-In methods, open the Google configuration, and add there all you client IDs, to the whitelist of client IDs from external projects.
If you are using Google Sign-In on a web application:
Click to open your web client ID and take note of both the client ID and secret.
Input this Client ID into your Firebase project’s configuration:
Go to the Firebase console at https://console.firebase.google.com
Open the Auth section
Under Sign-In methods, open the Google configuration, and add the values under the Web SDK configuration section.

Google App Engine access firebase in different project

I have setup app engine and firebase at PROJECT A, the app engine used default credentials, and able to access firebase at PROJECT A, however the app engine also need to call
verifyIdToken()
to verify user in PROJECT B.
What would be the best approach to it?
I can download the firebase credentials from PROJECT B, and use firebase admin sdk to do so, but it seems overkill, because i only needs to verify use token.
Setup firebase IAM permission in PROJECT B for app engine from PROJECT A, so it can access to firebase, theoretically, but in this case, how the app engine get the credentials from firebase in PROJECT B? Definitely not default credentials, right?
You can add the necessary roles from Project B to the service account used by Cloud Functions (it will be <project-a>#appspot.gserviceaccount.com). You would do this by visiting the Google Cloud IAM console in Project B and assigning the roles appropriately.
Once you do that, you should be able to use default credentials to authorize requests for Project B.
Note: There's some nuance here and I haven't directly tried this, but it should work in theory.
Found the solution
using_a_service_account_id
and
Answer from another post
After setup the IAM role and policy in project B with project A accouint, simply just do
projectB_firebase = firebase_admin.initialize_app(options={
"serviceAccountId": "firebase-adminsdk-xxxxxxx#[projectb].iam.gserviceaccount.com"
}, name="projectB")

How to configure Flutter apps to share Cloud Firestore

I have 2 Flutter applications -- let's call them A and B.
Each application uses Firebase Authentication and Firebase Analytics (and maybe more Firebase services in the future).
Both applications need to access a shared Cloud Firestore, and that access obviously needs to be secure.
So how can I best do this?
I have created 3 Firebase Projects:
Project A for Flutter application A -- enabled Auth and Analytics
Project B for Flutter application B -- enabled Auth and Analytics
Project C for Cloud Firestore
For the two Flutter applications, I have downloaded the respective GoogleService-Info.plist files and placed them in the project's ios/Runner directory. Each application can successfully login and capture analytics events, and I can clearly segregate activity between the two applications.
Now, I need to point both A and B to C. I first thought that I could simply update the DATABASE_URL in both GoogleService-Info.plist files, but that doesn't seem to work.
I have read the Configure multiple projects
documentation, and I can imagine having a secondary GoogleService-Info.plist file for the Cloud Firestore, perhaps named GoogleService-Info-DB.plist, but then how does one get FirebaseApp to load the secondary configuration? (Note that iOS needs to load the secondary plist, and Android needs to load a secondary json file.) I only see a configure method that accepts a FirebaseOptions class.
Related, I need to secure Project C's database to only authenticated users from Project A or Project B. How can I do that?

Firebase Service Account for Firestore and Remote Config

I have created/forked a lil Google Apps Script Library to manage Firebase Firestore and Firebase Remote Config called FirebaseGoogleAppsScript. The goal is to simply manage the contents of your collections in an apps script as well as update your remote config.
My issue is I can't get the a service account to do both.
Firebase creates two service accounts upon creating a project:
The first is listed in the Firebase Console -> Project Settings -> Service Accounts. This one I use within my cloud functions to retrieve the Remote Config just fine. However in the Apps Script Project it is unable to retrieve any data from firestore. I tried adding all kinds of roles including Owner and Editor yet no firestore data, but I still can get the RemoteConfig.
The second is only visible in the GCP service accounts and has the title: Firebase Admin SDK Service Agent with the roles Firebase Admin SDK Administrator Service Agent and Service Account Token Creator. This one is able to retrieve all the data from firestore within an Apps Script Project. However in the apps script project I can't get it to retrieve the RemoteConfig even if I add the role Firebase Remote Config Admin.
I have also made my own service account which was able to get the Remote config and just about everything else from Firebase except the Firestore data. Seems only the one service account created by Firebase is able to get any data.
To recreate the issue simply deploy my lil FirebaseGoogleAppsScript project and associate it to the same GCP project Firebase is connected to. There is a test file in it which can recreate the issue assuming you have some data in RemoteConfig and a collection called posts with some docs.
What the heck is going on here? Why can't I make a service account who can access Firestore and RemoteConfig? Any ideas on what to do to create a proper role to do both? Do I really have to use two separate service accounts?

Resources