Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firestore User Management Best Practices?

So I'm developing a web app using Firestore and Nuxt, and while I got the authentication working I would like to ensure I am following best practices.

Using Firebase Authentication only gives me an identifier (email in this case) and an UID. Then I created a user collection to store additional data such as:

{
  "UID": "6TIupYLKlcOE97b5Fe63uinf6Ik1",
  "app_metadata": {
    "role": "admin",
    "status": "approved"
  },
  "firstName": "Jon",
  "lastName": "Doe"
}

Currently I am doing the following after user is authenticated to get the user's role:

// Getting user details
db.collection('users')
.where('UID', '==', user.uid)
.limit(1)
.get()
.then((snapshot) => {
  snapshot.forEach(doc => {
    console.log(doc.id, '=>', doc.data().app_metadata.role)
    dispatch('setROLE', doc.data().app_metadata.role)
  })
})
.catch((err) => {
  console.log('Error getting documents', err);
})

Is there a better way to handle storing additional user data and tie it all together with Firebase Authentication?

like image 241
Chris F. Avatar asked Oct 28 '25 14:10

Chris F.


2 Answers

That question leads to another question: best practice for handling application state (which includes user state). So, it's actually a great question and there is a best practice (a non-opinionated answer). Below is based on standard JavaScript. I'm not familiar with vue or nuxt frameworks.

Regarding storing user profile data, best practice is to create a users collection in your data store, practically in Firestore (the next-gen version of RTDB). Use the firebase.auth().currentUser.uid as the document id/name for each user record (or document, in Firestore lingo). The firebase.auth().currentUser object is populated via the .onAuthStateChanged observer. So, you would say firebase.firestore().collection('users').doc(firebase.auth().currentUser.uid).update({age:25}) to save the users age, for example.

Not done though.

You don't want to have to query the data store each time you need to read user profile data. So, what you do is attach a realtime listener (.onSnapshot) to the users document upon signin. Have an app-level/global variable called userDocument and do userDocument = userDoc. userDoc being the object returned to you by your realtime update.

Now all you gotta do is read that local userDocument variable (instantly, no fetch delay). This approach is best practice for other data such as shopping carts (documents) as well.

So, the answer is 2 part: user profile data such as age, favorite color, shopping cart id, etc is stored in a users collection under the uid provided by firebase.auth(). Then, finally, subscribe to that user document so that upon any changes to it, your app (script) is immediately refreshed with all that data (vs fetching it on demand).

like image 81
Ronnie Royston Avatar answered Oct 30 '25 05:10

Ronnie Royston


A more conventional way is to use the UID as the ID of the document. This lets you find the document simply by saying:

db.collection('users').doc(uid).get()   // either 0 or 1 document

This is easier than having to do a query and having to perform a query with a limit. When what you have now, what happens if 'users' accidentally gets two document for a particular uid?

like image 21
Doug Stevenson Avatar answered Oct 30 '25 03:10

Doug Stevenson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!