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
Custom Usernames With Firebase Authentication and Angular
Episode 16 written by Jeff DelaneyFirebase authentication is super convenient, but you can’t easily assign custom usernames out of the box. In this lesson, we are going to give users custom usernames and asynchronously validate their availability during the signup process. On every keyup, the username will be checked for duplicates, so we can display a helpful message to the user.
When a user signs in via OAuth, the app will see if they have a username set. If they do NOT, it will keep them on the login component and force them to enter a username, which will validate username availability asynchronously.
ng g service auth |
Modeling the Username Data
Our database will have a collection of users for general record keeping, but the quickest way to asynchronously check username availability is to save all usernames in their own collection, with the keys being the usernames that are not available to new users.
users |
For example…
users |
AuthService that Verifies Username Availability
First, let’s create a User
class to simplify the auth object. We only care about the uid
and the username
. As a constructor, it will take the Firebase AuthState from angularfire2.
We need to subscribe to both the authState
and the user information in the database at the same time… So how do we handle nested subscriptions with RxJS? In this case, we are going to use switchMap, which will emit the Firebase auth object first, then get the user values from the database, returning everything as an observable. Using switchMap
avoids nested RxJS subscriptions (generally considered a bad practice).
auth.service.ts
import { Injectable } from '@angular/core'; |
We need to make sure the username is available before it can be selected. First, the username collection is queried with the user’s text input. Querying with this method only targets a single key value pair, rather than an entire list, so it’s much faster. In fact, it’s almost instantaneous in the UI as you will see. We also use a getter to check if the current user has a username. Here’s how the remainder of the service is filled out.
get hasUsername() { |
Login Component with Username Validation
We will run a query to Firebase after each keydown
event to see if there’s a matching username in the database. If not, the user can go ahead and select it.
user-login.component.ts
import { Component } from '@angular/core'; |
A new user will start by authenticating with Google. When that is successful, the form input to select a username is displayed.
When there’s a matching username, the usernameAvailable
variable is set to false. In the template, we use this variable to display a success or error message. It is also used to disable the submit button.
user-login.component.html
<h1>Login</h1> |
Validating a Unique Username via Firebase Database Rules
The current username validation is great as a frontend UX feature, but it is still vulnerable to accidental duplication. Let’s add an extra layer security by creating a firebase database rule that ensures a username cannot be accidentally duplicated on the backend.
database.rules.json
"users": { |
That’s it for custom usernames with firebase.