Search code examples
reactjsfirebase-realtime-databasefirebase-authenticationgoogle-cloud-functionsfirebase-admin

Firebase onCreate add custom claims to the auth.user


I am trying to add a custom claims, isRegistered to firebase. My firestore has another user collection to keep register info records. Now I am trying to keep a isRegistered custom claim but I can not seem to get it work.

exports.addRegisteredRole = functions.database.ref('/user')
    .onCreate((snap, context) => {
      return // **I added this later, but the issue still remains.**
        admin.auth()
            .setCustomUserClaims(context.auth.uid, {isRegistered: true})
            .then(() => {
                console.log('done', snap)
                return {
                    message: 'done',
                    data: snap
                }
            })
            .catch(err => {
                console.log('something went wrong', err);
                return err
            })
    });

I am checking this claim by,

currentUser.getIdTokenResult()
        .then(res => {
            console.log(res.claims.isRegistered)
        })

(auth user object). Even if I re-logged it remains undefined. Am I doing something wrong, I am very new to firebase.


Solution

  • The issue is with your onCreate trigger. You assumed you're getting the uid in the context.auth object, which is not correct.

    The onCreate trigger will be triggered automatically on the addition of a new document in your "user" collection. In this case, the context.aut.uid is undefined. You should trace this in your function logs.

    You can achieve what you are trying to do in a couple of ways

    1. If the user record document has the the user Id as the name of the document, you can do the following
    exports.addRegisteredRole =
      functions.firestore
        .document('test/{docId}')
        .onCreate((snap, context) => {
          admin.auth()
            .setCustomUserClaims(snap.id, { isRegistered: true })
            .then(() => {
              console.log('done', snap)
              return {
                message: 'done',
                data: snap
              }
            })
            .catch(err => {
              console.log('something went wrong', err)
              return err
            })
        })
    
    1. If you're naming the user record document with something else, or letting firebase decide the name for you, then you must have the uid as an attribute in the document data. Then you use docSnapshot.data().uid instead of docSnapshot.id as follows
    exports.addRegisteredRole =
      functions.firestore
        .document('test/{docId}')
        .onCreate((snap, context) => {
          admin.auth()
            .setCustomUserClaims(snap.data().uid, { isRegistered: true })
            .then(() => {
              console.log('done', snap)
              return {
                message: 'done',
                data: snap
              }
            })
            .catch(err => {
              console.log('something went wrong', err)
              return err
            })
        })
    

    Good luck