0

I am using google identity provider to sign into firebase projects. Now I would like to use one identity provider project to sign into multiple cloud firestores. Mainly I want user to be able to sign up for a test environment with the same account as they do on production.

I checked the solution here: Firebase Auth across multiple projects with different Providers but unfortunately it's not working for me. I am getting "This operation is restricted to administrators only."

Currently my code looks as following:

DB / Firebase setup

  constructor() {
    this.app = firebase.initializeApp(environment.firebase);
    this.database = firebase.initializeApp(environment.database, 'secondary');
  }

DB Auth

  private async initializeDb(firebaseUser) {
    const token = await firebaseUser.getIdToken();
    const provider = new firebase.auth.OAuthProvider('oidc.prod-login');
    const credential = provider.credential({ idToken: token });
    await this.firebaseService.database.auth().signInWithCredential(credential);
    return firebaseUser;
  }

In my test environment I configured the OIDC provider as following:

name: prod-login client ID: main-firebase-project-id issuer: https://securetoken.google.com/main-firebase-project-id

Did I miss something?

Dharmaraj
  • 47,845
  • 8
  • 52
  • 84
dom
  • 509
  • 1
  • 7
  • 13
  • Try to pass the app firebase (this.app) into the `signInWithCredential` as you have 2 firebase in your project, you need to specify exactly the one signing in. Also the same as the "auth sign" (I supposed this.database) when you first log in – Alejandro Barone Feb 03 '23 at 13:23

1 Answers1

1

You can use Firebase admin OR Firebase functions with firebase admin configured to generate Custom tokens with the same User ID token. Then use this token to authenticate with the second project on the client side.

  1. First, initialize the Firebase Admin for the first project Like the one provided here :
const admin = require("firebase-admin");

admin.initializeApp({
  credential: admin.credential.cert({
    "projectId": "<PROJECT_ID>",
    "privateKey": "-----BEGIN PRIVATE KEY-----<KEY>-----END PRIVATE KEY-----\n",
    "clientEmail": "foo@<PROJECT_ID>.iam.gserviceaccount.com"
  }),
  databaseURL: "https://<DATABASE_NAME>.firebaseio.com"
});
  1. Verify the user's ID token from the First Project using Firebase Admin and Use the verified user's ID token to create a custom token for the second project then Pass the custom token to the client SDK:
const idToken = "userId-token-from-FirstProject";

admin.auth().verifyIdToken(idToken)
  .then((decodedToken) => {
    const uid = decodedToken.uid;
    // Create a custom token for the second project.
    return admin.auth().createCustomToken(uid, { projectId: "<PROJECT_ID_2>" });
  })
  .then((customToken) => {
    // Pass the custom token to the client SDK
    res.send({ token: customToken });
  })
  .catch((error) => {
    console.error("Error creating custom token:", error);
    res.status(500).send({ error: error });
  });
  1. Use the custom token to authenticate with the second project on the client-side of second project:
firebase.auth().signInWithCustomToken(customToken)
  .then((result) => {
    // The user is authenticated with the second project.
    console.log("User signed in with custom token:", result.user.toJSON());
  })
  .catch((error) => {
    console.error("Error signing in with custom token:", error);
  });

Although this will work, I think there should be a delay given for the Client side to authenticate with the seconds project as we are re-authenticating with a custom token.

For different OIDC providers I think this answer makes more sense

For info go through these links which also covers this topic:

Rohit Kharche
  • 2,541
  • 1
  • 2
  • 13