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
Multiple Device Push Notifications With FCM and Firestore
Episode 64 written by Jeff DelaneyA few months ago, I released a video covering Firebase Cloud Messaging (FCM) with the Realtime Database. Today, I am going to update this code with the following improvements:
- Save FCM tokens in Firestore.
- Send Firebase push messages to multiple devices simultaneously.
- Angular 5
Setting Up Firebase Cloud Messaging in Angular
There are several steps you must take in Angular to get started with cloud messaging.
User Auth
Before you can take advantage of messaging, you need to have a user authentication system in place that can manage custom data. I recommend using my Firestore OAuth setup, but it’s not required. The important thing is that you have a custom user document in Firestore with an ID that matches the user’s auth UID. Here’s what our custom user interface looks like:
interface User { |
The fcmTokens will be mapped to the user document. The resulting document looks like this in plain JS. Each token represents a different device to which the user has granted messaging permission
{ |
App Manifest
All progressive web apps must have a src/manifest.json file. The main part we care about here is the GCM sender ID. Keep in mind, this value is the same for ALL apps - do not use your unique Firebase messaging ID here.
{ |
Then link it in the head of the index.html
.
<head> |
Service Worker
Firebase makes the service worker code for push messaging dead simple. The worker just sits in the background and listens for messages. Make sure to use this exact name and file location: src/firebase-messaging-sw.js
. You can retrieve the messagingSenderId
from the Firebase admin console.
importScripts('https://www.gstatic.com/firebasejs/4.6.1/firebase-app.js'); |
CLI Json
Lastly, register these files in angular-cli.json
.
"assets": [ |
Receive Push Messages in the Angular Front-end
There are several steps involved in receiving push messages.
- Get permission from the user on a given device.
- Update the permission token in Firestore
- Listen for new messages when the app is active.
All of this logic will be handled from a service:
ng generate service messaging |
Here’s our initial service code to which we will be writing additional methods.
import { Injectable } from '@angular/core'; |
1. Get Permission from the User
Every platform that sends push messages must first gain permission from the user. We’re going to be focused on the web using the JavaScript SDK, but similar principles apply to iOS and Android settings.
We are also going to monitor the token refresh. If the token changes, we will update it in Firestore to ensure the user still receives notifications.
// get permission to send messages |
2. Save the Token in Firestore
Tokens are saved directly on the user document. You might also save them as a subcollection, but most users will only have 0 to 5 tokens, so the memory impact is miniscule. If the token already exists, then there is no need to run the update.
// save the permission token in firestore |
3. Receive Messages in Angular
When the app is closed, the web worker will transmit the message via the browser. However, this is not desirable when the user is actively working in the app. What we can do instead is listen for messages, then display the notification inside the app.
// used to show message when app is open |
App Component
In this example, I am going to request permission from the user via the app component. First, I subscribe to the current user’s data. This only needs to be done once, so I am using take(1)
to complete the subscription after receiving the first user document.
import { Component, OnInit } from '@angular/core'; |
User Specific Messaging to Multiple Devices
User specific messaging is used when something important happens to a single user. For example, a user might want to know when they are mentioned in a tweet or when their order has been shipped. In this example, are going to send a notification to users when they have received a new text message from another user.
FCM Cloud Function
Firebase Cloud Functions will serve as the backend environment for sending messages. The function will be triggered when a new message document is created in firestore. Each message has a recipientId
and a senderId
. The push notification will be broadcast the recipient’s devices.
const functions = require('firebase-functions'); |
const functions = require('firebase-functions'); |
Deploy the function using:
firebase deploy --only functions |
Manually add a new message document to firestore with the current user’s UID and you should see the notification displayed in your app.
The End
Push messaging is one of the most important features of Progressive Web Apps (PWA). Today we learned how you broadcast messages to a single user. In the next lesson, I will show you how to send messages to multiple users simultaneously based on topic.