I want to make Firestore’s rule using Firebase custom token like this.
match /post/{postId}{
allow create: if request.auth.token[role] == `admin`;
allow read: if request.auth.token[role] == `admin`;
}
When a user sign up an app, I want to give her its role using cloud functions.
This is here.
const functions = require('firebase-functions');
export const updateAcl = functions
.firestore.document("/members/{memberId}")
.onCreate(async(user, context) => {
await getAuth().setCustomUserClaims(user.uid, {role:'admin'});
});
The flow is here.
- A user sign up the app.
- The user will be given an role in async backend.
- Using custom claim the content will appear.
But this has a problem. Because of the timing.
When the user got the role using backend’s async cloud functions, the content already appeared.
First time when it shows, her doesn’t have her role yet.
I mean before the content appear, her should have her role.
Cloud functions onCreate
doesn’t have sync now.
How can we solve it?
2
Answers
Custom claims won’t refresh in rules immedately untill they Propagate custom claims to the client, You can force refresh ID token by calling
currentUser.getIdToken(true)
to propagate custom claims on client after you callsetCustomUserClaims
via admin sdk.All I can think to tell client after custom claims changed is write data to firestore or rtdb:
Alternative, also is my prefer one, is simply just use firestore to implement Role-Based Access Control, You can use admin uid as document id, then write this document to a collection call admins, And rules look like this:
You can use a
beforeCreate
blocking function. You’ll need to upgrade your project to Firebase Authentication with Identity Platform (it’s free up to 50K MAUs IIRC)You can then write your function like this:
The Firebase docs have an example
Don’t forget to register your blocking function in the Authentication console. (I’m not sure if the "non blocking" functionality of them will still work without registration, but you definitely need to register the function if you want to be able to block user sign in/up)