Luiz Ricardo Cardoso
Luiz Ricardo Cardoso

Reputation: 1624

Create user and set customClaims with Firebase Authentication

When I register a new user I'm setting up some values for user access control right away.

The problem is that the data I am setting is only being displayed in the next sessions after you have logged out of the authenticated user session after you have created it.

So my problem is that I can not get claims after I have created an account and then have defined it, I need this data soon after creating a new user in Firebase Authentication.

auth.service.ts

public user: any;
public firestoreCollection: string;
public admin: boolean;

constructor(private _angularFireauth: AngularFireAuth) {

    this.getUser().subscribe((user: firebase.User) => {

        this.user = user;

        if (this.user) {
            // You must logout() and then login() to get the claims.
            user.getIdTokenResult().then(idTokenResult => {
                this.firestoreCollection = idTokenResult.claims.firestoreCollection;
                this.admin = idTokenResult.claims.admin;
            });
        }
    });
}

public getUser(): Observable<firebase.User> {
    return this._angularFireauth.authState;
}

public async createAccount(user: any): Promise<void> {
    const auth = await this._angularFireauth.auth
        .createUserWithEmailAndPassword(user.email, user.password);

    const userObject = {
        displayName: user.nome.trim(),
        photoURL: 'assets/images/avatars/profile.jpg'
    };

    await auth.user.updateProfile(userObject);

    const setUserControlAccess = firebase.functions()
        .httpsCallable('setUserControlAccess');

    await setUserControlAccess({
        admin: true, assinante: true, profissional: true,
        firestoreCollection: auth.user.uid,
        email: auth.user.email
    });

    // I tried to re-authenticate to see if I could get claims.
    await this.reauthenticateUser(user.email, user.password);
}

Cloud Functions

 export const setUserControlAccess = functions.https.onCall(async (data, context) => {
     try {
        const customUserClaims = {
        admin: data.admin,
        firestoreCollection: data.firestoreCollection
    };

    const user = await admin.auth().getUserByEmail(data.email);
    await authentication.setCustomUserClaims(user.uid, customUserClaims);

} catch (error) {
    console.error(error);
    return error;
}
 });

Upvotes: 1

Views: 1492

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599661

If you need the user roles straight away, consider using a different mechanism than custom claims for them. Typically storing this information in the database ensures that it is available straight away and scales better. Custom claims are typically better used for things that are less volatile, like identifying application administrator. For more on this, see the video Five tips to secure your app.

That said, you can force the reload the user's profile to get the latest token changes (including the claims). If that doesn't work, the user will have to sign out and in again.

Upvotes: 1

Related Questions