Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add metadata to Firebase authentication

I need to pass a custom value (device_id) during google signin with firebase authentication. This value is later obtained from cloud functions by listening for authentication event triggers and then the value is added to Firestore

I understand that you can pass values as query parameters for http triggers. However I only need to pass and get the value during and after authentication in my case. Hence is there some sort of auth.addMetaData(metadata) function in firebase authentication?

I need to be able to retrieve the custom data after an auth trigger just like we can do user.email. I need something like user.custom_data

like image 393
Urchboy Avatar asked Aug 30 '19 16:08

Urchboy


2 Answers

Although Doug mentions Firebase Custom Claims, I think it’s worth extra documentation because it does allow you to add simple metadata to a Firebase User object.

Important notes

  • Big caveat: Custom claims are only refreshed when the user logs in. So an isAdministrator claim would require the user to logout/login before it is activated.
  • Firebase recommends “Use custom claims to store data for controlling user access only. All other data should be stored separately via the real-time database or other server side storage.”

Set metadata (server only)

Here’s an example on how to set device_id on a Firebase User object (on the server using firebase-admin):

await admin.auth().setCustomUserClaims(uid, { deviceId })

Note: You can not set custom claims on the client.

Get metadata (server and client)

Then to retrieve the the device_id from the User on the server:

const userRecord = await admin.auth().getUser(uid)
console.log(userRecord.customClaims.deviceId)

…and on the client:

const idTokenResult = await firebase.auth().currentUser.getIdTokenResult()
console.log(idTokenResult.claims.deviceId)

Use metadata in Firebase Security Rules

The neat thing is that custom claims are also available in Firebase Security Rules. This (slightly unrealistic) example only allows users with deviceId === 123 to see the data:

{
  "rules": {
    "secureContent": {
      ".read": "auth.token.deviceId === 123"
    }
  }
}

More information

  • Official docs: https://firebase.google.com/docs/auth/admin/custom-claims
  • Deep dive: https://medium.com/google-developers/controlling-data-access-using-firebase-auth-custom-claims-88b3c2c9352a
  • A clever pattern of synching custom claims with a Firebase database collection: https://medium.com/firebase-developers/patterns-for-security-with-firebase-supercharged-custom-claims-with-firestore-and-cloud-functions-bb8f46b24e11
like image 120
Tom Söderlund Avatar answered Sep 20 '22 16:09

Tom Söderlund


Firebase Authentication doesn't support any sort of extra data provided by the client. The closest thing to metadata that gets stored per user by Firebase would be custom claims, however, the JSON blob stored there can only be set by privileged server-side applications.

If you need to store data per user, written by client apps, you should probably be using a database for that (Cloud Firestore or Realtime Database), protected by Firebase security rules, so that only the end user can read and write their own data. You could also use an HTTP type Cloud Function to pass data into your function to be recorded in a database.

like image 39
Doug Stevenson Avatar answered Sep 22 '22 16:09

Doug Stevenson