Assign Firebase Auth Claims via Firebase Cloud Functions Nodejs

May 4, 2021

NOTE: Cloud Functions by Firebase vs Cloud Functions

const functions = require('firebase-functions');
const admin = require('firebase-admin');

const app = !admin.apps.length ? admin.initializeApp() : admin.app();
const db = admin.firestore();

// check is admin using custom claims or hard coded uid
function isAdmin(context) {
  return context.auth && (context.auth.token.admin || context.auth.uid == 'vVShHjZZ2lMV2LI01vNZkpKoioh1')
}

exports.assignUserRole = functions.https.onCall(async (data, context) => {
  // secure this function to ensure only admin could access
  if (!isAdmin(context)) {
    throw new functions.https.HttpsError("permission-denied", "You are not admin.")
  }

  // valudation
  if (!data.uid) {
    throw new functions.https.HttpsError("failed-precondition'", "Missing uid.")
  }

  const uid = data.uid
  if ('moderator' in data) {
    // set custom claims: true or false
    await admin.auth().setCustomUserClaims(uid, { moderator: data.moderator })

    // update firestore
    const userRef = db.collection('user_private').doc(uid);
    if (data.moderator) {
      await userRef.update({
        roles: admin.firestore.FieldValue.arrayUnion('moderator')
      })
    }
    else {
      await userRef.update({
        roles: admin.firestore.FieldValue.arrayRemove('moderator')
      })
    }
  }

  return data
});

References:

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.