Ad

How To Set New Property In User Metadata?

I'm trying to set some property in user metadata. I'm trying to do this using https://firebase.google.com/docs/auth/admin/manage-sessions#revoke_refresh_tokens and then https://firebase.google.com/docs/auth/admin/manage-sessions#update_user-specific_metadata_in.

Probably I'm doing something wrong, because it's not working. If I do this like in this article, and then call auth().listUsers to get the users data, 'metadata' has only default properties: creationTime and lastSignInTime, but without the new property revokeTime, any idea?

Edit:

My revoke function:

export const revokeUsersToken = functions.https.onCall(async (req, res) => {
  const admin = await import('firebase-admin');

  if (!isRevokeUsersTokenInitialized) {
    admin.initializeApp();
    isRevokeUsersTokenInitialized = true;
  }

  return admin
    .auth()
    .revokeRefreshTokens(req.uid)
    .then(() => {
      return admin.auth().getUser(req.uid);
    })
    .then(userRecord => {
      return new Date(userRecord.tokensValidAfterTime as string).getTime() / 1000;
    })
    .then(timestamp => {
      const metadataRef = admin.database().ref('metadata/' + req.uid);

      metadataRef.set({ revokeTime: timestamp }).then((x) => {
        return `Database updated successfully: ${x}`;
      }).catch(error => {
        return `Error: ${error}`;
      });
    });
});

Then, when I try to get all users:

export const getListUsers = functions.https.onCall(async (req, res) => {
  const admin = await import('firebase-admin');

  if (!isGetListUsersInitialized) {
    admin.initializeApp();
    isGetListUsersInitialized = true;
  }
  const maxResults = 100; // optional arg.

  return admin
    .auth()
    .listUsers(maxResults)
    .then(userRecords => {
      return userRecords.users.map(user => {
        const {
          passwordHash,
          passwordSalt,
          phoneNumber,
          photoURL,
          providerData,
          tokensValidAfterTime,
          customClaims,
          ...us
        } = user;
        return {
          ...us,
          role: customClaims && customClaims.hasOwnProperty('role') ? (customClaims as any).role : null
        };
      });
    })
    .catch(error => console.log(error));
});

and if I get this users list there is not info about new metadata property

Ad

Answer

The documentation you linked describes how to revoke access for a user to the database, without waiting for that user's ID token to expire. To accomplish this, it uses two products: Firebase Authentication, and Firebase Realtime Database.

But the two products have no knowledge of each other, so the revokeTime you write to the database won't show up in the user's authentication record.

Ad
source: stackoverflow.com
Ad