You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Associate Firebase Users to Database Records
Episode 19 written by Jeff DelaneyIn this lesson, we are going to associate database records with users who authenticated via Firebase. Code originally produced in the realtime database lesson will be refactored maintain a relationships with Firebase users. You don’t need to go through that lesson, but it wouldn’t hurt. First, let’s talk about how data relationships are managed in a NoSQL database.
Thinking in NoSQL Terms
If you come from a SQL background, you’re used to modeling data around the concept of relationships. In NoSQL, you don’t model data based on relationships, but rather on queries you plan to run against it.
In NoSQL, you should always ask “What is the most efficient way to query this data?”, because operations must be executed quickly. Usually, that means designing a database that is shallow or that avoids large nested documents. You will probably need to duplicate data and that’s OK - I realize that might freak you out if you have a SQL background. Consider this fat and wide database design:
Usually a Bad Idea in NoSQL
-|users |
Now imagine you wanted to loop over the users just to display their usernames. You would also need load their posts, the post comments, and the likes – all that data just for some usernames. We can do better with a tall and skinny design.
Refactoring to a Shallow Design
-|users |
Not only does this offer better performance on individual queries, it keeps the logic in distinct areas. Now that we understand that concept, let’s create some actual data relations with Angular 4 and Firebase.
1. When Data is Queried based on the User
When you have data that you plan on querying based the authenticated user, such as a user’s twitter feed, you can nest data under the Firebase auth.uid.
-|items |
The relationship is created by nesting items under the user ID
The Items Service
In order to get the items associated we need to obtain the current user’s ID from Firebase.
In the service, we subscribe to the AngularFire2 AuthState
, which will emit the user’s uid. Now we can query the database to get items that belong to the user because they are nested under this unique ID. Notice this.userId
is added to the db.list
call.
import { Injectable } from '@angular/core'; |
Backend Security with Firebase Rules
It is important to secure data on the backend. In this example, we only want the current user to have read/write access to their data. We can do this by matching a wildcard variable $uid
to the auth.uid
.
"rules": { |
2. When Data is Queried based on the Item
Sometimes data has a user association, but does not get queried by the user, such as a comment feed, votes, etc. In this case, you can set the association on each item.
-|items |
Updated Service
This user relationship is tracked by giving the Item
class a userId
attribute. When a new Item is created, the attribute is updated with the current user’s uid. All other service code remain the same, with the following minor changes:
export class Item { |
Firebase Rules
This rule grants write access if the the data’s userId
matches the auth.uid
OR it isnull
, which would be expected when creating a new item.
"$itemId": { |
3. Data that Belongs to Multiple Users
Some data can be associated with multiple users, such as a collaborative project or chat room. In that case, you can set the uid as the $key
with a value of true
.
-|items |
Membership Style Service
In this scenario, users can join()
or leave()
an item. We will grab an object observable from the database based on the item’s push $key
, then update or remove the current user’s uid in the members section.
join(itemKey) { |
Firebase Rules
In this scenario, backend rules can be similar to method two based on the user that created the item. Alternatively, you could assign certain certain members at moderator attribute. Check out the Firebase Database Examples Lesson for more advanced backend rule ideas.
That’s it for user data relationships with Firebase and Angular.