Reputation: 1068
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.
Upvotes: 4
Views: 4620
Reputation: 55
Most likely the problem is that you didn't propagate the new custom claims to the client. See here: https://firebase.google.com/docs/auth/admin/custom-claims#propagate_custom_claims_to_the_client
This github issue points that out as well: https://github.com/firebase/firebase-tools-ui/issues/424
If you log out and log back in with the user, it should work. Simply refreshing the page for a logged in user doesn't refresh the user's ID token.
As setting custom claims in the onCreate trigger is a common use case, it would be nice to have a note on this in the docs (https://firebase.google.com/docs/auth/admin/custom-claims) specifically for firestore, as the given example is for the realtime db.
Upvotes: 1
Reputation: 973
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
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
})
})
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
Upvotes: 1
Reputation: 1691
I think you should use functions.firestore.document with wildcard to trigger your "user" documents:
exports.addRegisteredRole = functions.firestore.document('/user/{userId}')
.onCreate((snap, context) => { ... });
Upvotes: 0
Reputation: 599041
I suspect that your Cloud Function gets terminated before the call to Auth completes. The reason for that is that you're not returning anything from the top-level of your code, which means that Cloud Functions assumes that your code is done once the final }
runs. But since the call to `` is asynchronous, that call hasn't completed yet and for example your console.log('done', snap)
won't have run yet.
exports.addRegisteredRole = functions.database.ref('/user')
.onCreate((snap, context) => {
return 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
})
});
Upvotes: 0