treesandgreens
treesandgreens

Reputation: 73

How to set custom auth claims through Firebase and identify platform

I am following the firebase documentation here to set custom auth claims for users logging into my app for the first time using firebase auth + identify platform but it does not seem to be working.

When a user logs in for the first time, I want them to get the admin custom claim. I have created the following blocking function and have verified from the logs that it runs when I log in for the first time to my app using sign-in with google:

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  return {
    customClaims: {
      admin: true,
    },
  };
});

I would expect this to create the admin custom claim in the user's token. However, when I get a list of claims using another cloud function the admin claim does not appear.

exports.getclaims = functions.https.onRequest(async (req, res) => {
  const uid = req.query.uid as string;
  if (uid) {
    const user = await admin.auth().getUser(uid);
    res.send(user.customClaims);
  } else {
    res.sendStatus(500);
  }
});

If I set the claim using the admin SDK directly using the below cloud function, the admin claim does appear.

exports.setclaim = functions.https.onRequest(async (req, res) => {
  const uid = req.query.uid as string;
  if (uid) {
    await admin.auth().setCustomUserClaims(uid, {admin: true});
    res.sendStatus(200);
  } else {
    res.sendStatus(500);
  }
});

What am I doing wrong in the beforeCreate function?

Upvotes: 6

Views: 2606

Answers (3)

Gremash
Gremash

Reputation: 8308

There's an open GitHub issue regarding that. See sessionClaims content not getting added to the decoded token. Also, there's a fix that has been recently merged regarding this issue.

Upvotes: 1

Shmyhelskyi
Shmyhelskyi

Reputation: 177

Try to use onCreate method instead of beforeCreate how it is shown on the official docs

functions.auth.user().onCreate(async (user) => {
    try {
      // Set custom user claims on this newly created user.
      await getAuth().setCustomUserClaims(user.uid, {admin: true});

      // Update real-time database to notify client to force refresh.
      const metadataRef = getDatabase().ref('metadata/' + user.uid);

      // Set the refresh time to the current UTC timestamp.
      // This will be captured on the client to force a token refresh.
      await  metadataRef.set({refreshTime: new Date().getTime()});
    } catch (error) {
      console.log(error);
    }
  }
});

The main point here is that you need to create the user at first and then update claims and make the force update of the token at the client side:

firebase.auth().currentUser.getIdToken(true);

Upvotes: 1

M. Gallant
M. Gallant

Reputation: 294

From the snippet you provided, there does not appear to be anything wrong with beforeCreate as coded.

You may want to check you do not have a beforeSignIn that is overwriting the customClaims directly or via sessionClaims.

https://firebase.google.com/docs/auth/extend-with-blocking-functions#modifying_a_user

Upvotes: 1

Related Questions