Vee
Vee

Reputation: 25

Firebase: Create second Custom Token for "secondary" app

User is already authenticated with Firebase, using a custom token created in Node. I want to login to a second database in a different project in a similar way, using the admin SDK.

I can't find any info on how to create a custom token specifically for the second database. Regardless of which token I use to authenticate (on the front end) I of course get a "auth/custom-token-mismatch" firebase error with the message "The custom token corresponds to a different audience." Which to me it seems as though the "admin.auth().createCustomToken" below is creating it only for the first app, and the second time it's also creating it for the first app.

I can't find any info of where I would specify the app for which to create the token, for example admin.auth("secondary").createCustomToken.. or something similar. Below is the code in question. Thank you in advance for your time.

// CONNECT TO FIREBASE PROJECT 1

var firebaseConfig = {
    databaseURL: 'https://app1.firebaseio.com',
    apiKey: 'key1'
};

var credentials = admin.credential.cert({
    "type": "service_account",
    "project_id": "project_1_id",
    "private_key_id": "private_key_id_1",
    "private_key": "PRIVATE KEY 1",
    "client_email": "...",
    "client_id": "...",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
});

try {
    admin.initializeApp({
        credential: credentials,
        databaseURL: firebaseConfig.databaseURL
    });
} catch(err) {};

// CONNECT TO FIREBASE PROJECT 2

var firebaseConfig2 = {
    apiKey: "apikey",
    authDomain: "...firebaseapp.com",
    databaseURL: "...firebaseio.com",
    projectId: "project_2_id",
    storageBucket: "...appspot.com",
    messagingSenderId: "...",
    appId: "..."
};



var firebaseConfig2Credentials = {
    "type": "service_account",
    "project_id": "...",
    "private_key_id": "...",
    "private_key": "RPIVATE KEY 2",
    "client_email": "...gserviceaccount.com",
    "client_id": "...",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
};


try {
    admin.initializeApp({
        credential: firebaseConfig2Credentials,
        databaseURL: 'https://...firebaseio.com'
    }, "secondary");
} catch(err) {};

// GET FIRST TOKEN

var get_firebase_token = async (o) => new Promise((resolve, reject) => {
    admin.auth().createCustomToken(modules.btoa(o.email), {
        expiresAt: Date.now() + (1000 * 60 * 60 * 24 * 30),
        premiumAccount: true
    }).then(function(token) {
        resolve(token);
    }).catch(function(err) {
        resolve(null);
    });
});

firebaseConfig.token = await get_firebase_token(req.cookies);

// GET SECOND TOKEN - this is where I need help

var get_firebase_token2 = async (o) => new Promise((resolve, reject) => {
    admin.auth().createCustomToken(modules.btoa(o.email), {
        expiresAt: Date.now() + (1000 * 60 * 60 * 24 * 30),
        premiumAccount: true
    }).then(function(token) {
        resolve(token);
    }).catch(function(err) {
        resolve(null);
    });
});

firebaseConfig2.token = await get_firebase_token2(req.cookies);

Upvotes: 1

Views: 1275

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 598817

Your admin variable is initialized with the credentials for your first project. So tokens minted from this admin instance will only work with that first project.

To create tokens for another project, you'll need to create another FirebaseApp variable that is initialized with the credentials for that project.

For more on this, also see the Firebase documentation on initializing multiple apps with the Admin SDK, which contains this handy sample:

// Initialize the default app
admin.initializeApp(defaultAppConfig);

// Initialize another app with a different config
var otherApp = admin.initializeApp(otherAppConfig, 'other');

console.log(admin.app().name);  // '[DEFAULT]'
console.log(otherApp.name);     // 'other'

// Use the shorthand notation to retrieve the default app's services
var defaultAuth = admin.auth();
var defaultDatabase = admin.database();

// Use the otherApp variable to retrieve the other app's services
var otherAuth = otherApp.auth();
var otherDatabase = otherApp.database();

Upvotes: 4

Related Questions