React Native Push Notifications with Firebase
Last week, Swizec Teller wrote an fantastic tutorial on adding push notifications to your React Native app using Cloud Messaging and Cloud Functions. Swizec’s tutorial saved me a substantial number of hours in order to setup notifications in my react native project: he rocks.
In this story, I’m following-up by providing some tips and strategies for the last mile of your implementation. My use case for notification is the typical one for social networks. As a user, you receive a notification every time someone likes one of your post, or comments on it, or replies to a comment. You can see the flow here. Each user has his own notifications document in Firebase. Every time an action is done, we add a row to the document. Some actions need to notify several peoples. In this instance, we use Firebase fan-out capability.
Cloud Functions
Serverless architectures are great. And if you are not using Typescript or Flow: you really should. In a previous story, I shared some tips on setting up typescript for Cloud functions. We use a database trigger to listen for new notifications. These database triggers provide an extremely convenient way to specify a path component as a wildcard. Based on the data layout described above, our trigger looks like this:
// Listens for new messages added to /notifications/:uid/:nid
exports.sendNotification = functions.database.ref("/notifications/{uid}/{nid}").onWrite((event: any) => {
// Path segment values are read from event.params
const {uid, nid} = event.params;
const notification = event.data.val() as Notification;
const payload = {
data: { nid },
notification: {
body: formatBody(notification)
}
};
console.log(`Send notification to ${uid}: ${body}`);
return admin.messaging()
.sendToTopic(`/topics/${uid}`, payload)
.then((result: any) => console.log(result))
.catch((error: any) => console.error(error));
});
Once the notification is built, we send it to the users dedicated topic. Note the Notification type at like 5. This type has been generated from firebase bolt. As describe in this story, this ensure that refactoring you data model affects database rules, react code, and functions.
React Native FCM
On the React side, we ask for permissions to send notifications once the user is logged-in. If you are using Firebase for authentication, it looks like:
firebase.auth.onAuthStateChanged((user: any) => {
if (user) {
FCM.requestPermissions();
this.topic = `/topics/${user.uid}`;
FCM.subscribeToTopic(this.topic);
} else if (this.topic) {
// If the user is logged-out, we unsubscribe
FCM.subscribeToTopic(this.topic);
}
});
If the app is opened by the user tapping on a notification, we route the app to the appropriate location.
FCM.on(FCMEvent.Notification, async (notif) => {
if (notif.opened_from_tray) {
//nid has been sent in the data payload of the notification
const nid = (notif as any).nid;
AppRouter.notifications(nid);
}
if (Platform.OS === "ios") {
// Usual shenanigans goes here (see fcm starting example)
}
});
Et voilà
I hope this article was helpful to you, and I look forward to receiving your feedback.
Full-stack developer | Health Tech
6 年Perfectly clear, thank you very much William !