Push Notification with Firebase - From Zero to Hero 8

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Push Notification is one of the features that connect your app with the end-user. However, if you think that Push Notification is just a pop up to display a simple text message to end-user, think again. The Push Notification mechanism allows your app to perform more than just displaying a message to the user. To know what else the Push Notification can do, watch till the end of this tutorial video. Welcome back to JustCode Channel! Please support us by subscribing to our channel and like our video. If you have any questions in this tutorial, please leave a comment below. Today tutorial, we will continue to modify the Dictionary app we had created in the past tutorial to illustrate how to use the Push Notification mechanism. First, we need to know that there are two main types of notification. They are the local notification and remote notification. The local notification allows the app to create a notification and display within the device itself. The remote notification is created via a remote server and "push" to the registered devices. In this tutorial, we will concentrate on the remote notification via Firebase Cloud Messaging API. The Firebase provides a variety of services ranging from database storage, machine learning, authentication, cloud messaging, and much more. You can visit firebase.google.com for more information. Today, we will just concentrate on the Firebase Cloud Messaging (FCM), which is the remote push notification service. Apple also has its own Cloud Messaging service, which is the Apple Push Notification service (APNs) for iOS device. However, it is troublesome and time-consuming if we need to maintain the server application that uses both APNs and FCM API to push notification to iOS and Android devices. The main advantage of using FCM is that it allows you to push notification to both Android and iOS devices with a single API. FCM act as a proxy for APNs. To use Firebase services, you must have a valid Firebase account and set up a Project in the Firebase Console. We had done that in tutorial 5. If you are new to Firebase, please watch our tutorial 5 for detailed steps on Firebase setup. In this tutorial, I assumed that you already have a project set up in the Firebase console. We need to install a few npm modules require by the FCM. Let's bring up our terminal screen. Make sure you are in the JustCodeDict project folder. The modules we are going to install are the @react-native-firebase/app and the @react-native-firebase/messaging module. Key in the command as shown to perform the installation. Once the modules are installed, we need to issue the pod update Firebase/CoreOnly command in the ios folder. The reason is we had installed Firebase/CoreOnly in Tutorial 5 and there is a version update when we making this tutorial. If you are creating a new project, then you just need to issue the pod install command instead of the update command. We had completed the installation of the modules. Now, we need to perform some setup before we can use the Push Notification feature. First, we will set up the Push Notification for iOS. You are required to have a valid Apple developer account before you proceed. Open the JustCodeDict workspace in the ios folder via the Xcode. Click on the JustCodeDict project on the side menu. Select the Targets as JustCodeDict, then click on the Signing & Capabilities tab on the right of the screen. Make sure you had selected the correct Team under the Signing section and there is no signing error. You cannot use the same bundle identifier as this tutorial. You need to change the bundle identifier to a one that is not being used. Click on the + Capability on the top left of the tab screen. In the pop-up dialog box, double click on the Background Mode. This will add in the Background capability into the iOS app. In the Background Modes section, select the Background fetch and Remote notifications option. Now, click on the + Capability again and select the Push Notifications capability. We have completed the setup in Xcode. Now, login to your Apple Developer accounts via developer.apple.com. Once login, select Certificates, Identifiers & Profiles item. Then click on the Identifiers menu item on the left. Scroll down until you see the application bundle identifier for JustCodeDict and click on it. Scroll down until you see the Push Notification capability and make sure it is selected. Next, go back to the previous screen and select Keys. We need to generate a Key for the server app to send the notification to the iOS device. The server app in this case is the FCM, as the FCM acts as a proxy for APNs. Click on the + icon. Key in the name for the Key and click on the Continue button. This will bring you to the result page. Click on the Download button to download the key file. Please take note that you can download the key file for one time only. Make sure you don't lose the file, else you need to revoke the key and regenerate it. Next, we need to use the downloaded key file to configure the FCM so that FCM can push notification to the iOS device on behalf of APNs. Let's login to the Firebase Console via console.firebase.google.com. Once login, click on the JustCodeDict Project we had created in Tutorial 5. Click on the iOS app in the project and click on the gear icon to configure the application. In the Setting page, click on the Cloud Messaging tab. Under the iOS app configuration section, click on the upload link in the APNs Authentication Key subsection. Select the key file we had just downloaded and key in the Key ID. You can obtain the Key ID from the downloaded filename or Apple Developer Console. Click on the Upload button to save the changes. Now, we need to generate the FCM private key. Click on the Service accounts tab. We will be using Node.js Firebase Admin SDK to perform the notification sending. Make sure Node.js is selected and click on the Generate new private key button. This will download the FCM private key file. We will need this file later to code the admin SDK. We had completed the setup for APNs and FCM. Before we start coding, we need to understand how the Push Notification is sent via the FCM Admin SDK and its lifecycle in the device. The FCM Admin SDK has multiple ways to send a notification to the device. However, in this tutorial, we will concentrate on two ways. The first is to send a notification to an individual device base on the unique device token ID. The second way is by topic the device had subscribed to. A Push Notification consists of two parts. They are the notification and data parts. A Push Notification can have both notification and data part or either one. Now, let us understand the life cycle of the Push Notification when it reached the device. If the app is not running in the device or it is running in the background when a Push Notification reached the device, the device will fire the App's setBackgroundMessageHandler to handle the notification in the background. However, if the Push Notification only contains data without the notification part, then the setBackgroundMessageHandler will not be fired if the message priority for the Android device is not set to the high and content-available flag is not set to 1 for the iOS device. The setBackgroundMessageHandler is normally used to save the notification in the device so that the app can access it later if required. Please note that setBackgroundMessageHandler cannot update the app UI or change the app state. The next handler is the onMessage handler. It will be fired if the app is running in the foreground when the notification arrived. If this happens, the app needs to display the notification manually as the device OS will not display the notification for you. From the table you can see that the device OS will display the notification only if the app is not running or running in the background. Take note that if the notification only contains the data part, then the device OS will not display the notification at all even the app is not running. The next two handlers I am going to discuss is to handle the user interaction with the Push Notification. They are the getInitialNotification and onNotificationOpenedApp handler. The getInitialNotification handler will be fired if the app is not running when the notification arrived and the user had tabbed on the notification. The onNotificationOpenedApp handler will be fired if the app is running in the background when the notification arrived and the user had tabbed on the notification. Please take note that to test Push Notification, you need to have a physical iOS or Android device. Push Notification will not work in Simulator. Let's bring out the VS Code with the project folder opened. The first thing we need to do is to set the background message handler. Please note take that the background message handler must be outside the main app component. Open the index.js in the JustCodeDict folder. Import the messaging module from Firebase. Then we invoke the setBackgroundMessageHandler method to define the background message handler. For now, we just perform a console log on the received message in the handler. Next, in the ReduxApp functional component, we will take in a new parameter called isHeadless. The isHeadless parameter will be true if the app is launch by iOS when the Push Notification arrived. In Android, the isHeadless will be undefined. On iOS when a message arrives, the device silently starts the application in a background state so that the setBackgroundMessageHandler is triggered. However, the root React component also gets mounted. This can be problematic for some apps. To get around this problem, the messaging module injects a isHeadless prop to your root component which you can conditionally use to render or do "nothing" if your app is launched in the background. On Android, a Headless JS task is created and runs separately from the main React component. This allows your background handler code to run without mounting your root component. In the functional component, we will return null if isHeadless is true. Now, let's open the App.js file. Import the messaging module from Firebase. In the componentDidMount method under the App class component, we will request the messaging permission. This applies to the iOS device only. On Android, we do not need to request user permission. However, this method can still be called on Android devices and it will always resolve permission granted. After checking the permission, we need to invoke the getToken method. This method will return the unique device token for receiving notification. This token is the "address" the FCM uses to send the notification to the individual device. In normal practice, we will send the token back to our server app for storage so that the server app can send a notification to the device when required. For this tutorial, we will just perform a console log for the device token. The FCM server will receive the device token automatically without the need for the app to send the token. Next, we will define the onTokenRefresh handler. Whenever the device token had changed, the onTokenRefresh will be fired. Similar to the getToken method, we should save the latest token back to the server but for this tutorial, we will just log the token into the console. Follow by, we will define the onMessage handler to handle the received notification when the app is running in the foreground. For now, we will just log the notification into the console. We had completed is basic coding for the app to receive push notification regardless the app is running or not. Let's compile and run the app on the device. The app had launched in the device. From the console log, we will see the getToken returned the device token. With this token, we can send a notification to the device. We can send a notification to a device via Firebase Console or the Firebase Admin SDK. I will show you both way but I will concentrate more on the Admin SDK. Let's bring out the Firebase Console again. On the side menu, scroll down until you see the Cloud Messaging menu item and click on it. Then on the right of the screen click on the Send your first message button. Specify the notification title and text. You also can include an optional image URL. Click on the Next button and select the android app as the app is running on the android device. Click on the Next button again and select the schedule. We will select "Now" for this test. Click on the Next button again. We will skip the Conversion events by click on the Next button. Now, you will see the Custom Data section. This is where you can specify the data part for the notification. For now, we just leave it blank. Click on the sound dropdown list and select enable. Click on the Review button and then click on the Publish button to send the notification. From the app console log, we will see the onMessage handler is fired as the notification had pushed to the device. However, you may wonder why there is no notification shown on the UI? The reason is the app is running in the foreground, therefore, the app should be responsible for displaying the notification in the UI. Now, we will add an alert dialog to display the notification in the onMessage handler. Let's trigger another notification from the Firebase console. Now, you will see the app pop up an alert dialog to display the notification. Next, we going to test the push notification when the app is running in the background. However, this time we will try to use the Firebase Admin SDK to perform the sending of the notification. Let's create an admin folder outside the JustCodeDict project folder. In the new folder, let's issue the npm init command. Key in justcodedictadmin as the package name. Accept the default version by press the enter key. Key in a description for the server-side admin app. Accept the default entry point. Leave empty for test command, git repository, keywords, and author. Accept the default license. Press enter to accept the setting. We had created a blank Node JS application. To use the Firebase Admin SDK, we need to install the firebase-admin npm module. Issue the npm install firebase-admin --save command to install the module. Remember the FCM private key file we had download from the Firebase console? We will need the file for the admin app. Copy the file from the download folder to the admin folder. Now, bring out the VS Code and create an index.js file under the admin folder. Import the Firebase admin module and the FCM private key file as shown. Please take note that the filename for the FCM private key file will be difference based on the project you created in your own Firebase Console. Next, we need to initialize the SDK by invoking the initializeApp method. Within the method, we will provide the credential and databaseURL parameter as shown. Please take note that your databaseURL will difference from this tutorial. The first part of the URL is your Firebase Project ID which you can get from the Firebase Console, or the filename of the key file. Follow by, we will create the message payload as shown. First is the notification part, it contains the title, body, and optional imageUrl. Next, is the data part for the notification. We will leave it blank for now. The next part is the notification option for the android device. We will turn on the notification sound and set it as default. We will do the same thing for the iOS device under the apns payload. The last part of the message payload is the device token which this message is targeted to. We will copy the device token from the console log and paste it into here. We had done for the message payload. Now, we will proceed to send the notification by invoking the send method from the Admin SDK as shown. Now, let us run the admin app to send the notification to the device. In the terminal screen, let's issue the node index.js command and press enter. We will see the alert dialog pop up on the device screen. In the mobile app console log, we will see the log for the newly arrived message too. I had demonstrated how to send push notification from Firebase Console and via the Admin SDK. We also demonstrated how the mobile app receives and displays the notification when the app is running in the foreground. Now, let us try to send a notification to the device when the mobile app is running in the background. Let's minimized the mobile app in the device. In the admin app terminal screen, let's issue the same command again to send the notification. We will see the notification bar display by the device OS. The console log will also display the message is handled in the background, which is the setBackgroundMessageHandler. So far we had implemented the onMessage and setBackgroundMessageHandler method. There are two more handlers we need to implement. They are the onNotificationOpenedApp and getInitialNotification handlers. Let us define the onNotificationOpenedApp handler just below the onMessage handler. The onNotificationOpenedApp handler takes in an arrow function with the remoteMessage parameter as shown. This handler will be fired when the application is running in the background when the notification arrives and the user had tapped on the notification bar. For now, we will just perform a console log on the received message. Next, we will implement the same logic for getInitialNotification handler. This handler will be fired when the application is quit when the notification arrives and the user had tapped on the notification bar. Let's reload the application in the device. We will minimize the app into the background. At the admin terminal screen, let's send the notification again. Tap on the notification on the status bar and you will see the console log displayed that the notification had caused the app to open from background state. Let's quit the app in the device and trigger another notification in the admin terminal. Tap on the notification again. This time you will see the console log displayed that the notification had caused the app to open from quit state. I had covered the four main handlers for handling the push notification nd they are the setBackgroundMessageHandler, onMessage, onNotificationOpenedApp, and getInitialNotification handler. Till now, I had shown you how to send a notification to a device via the device token. Next, I am going to show you how to send a notification to multiple devices at once by using the notification topic. This is useful when you want to broadcast information to your end users instead of sending notification one by one. Before the app in the device can receive notification by topic, the app needs to subscribe to the specific topic. Open the App.js file in the JustCodeDict folder. Just above the onMessage handler, we will add in the topic subscription logic. We will create a topic called "dailyword". Assumed that our admin app will send a daily notification of a word to our end user. We had completed the topic subscription. Now, let's switch back to the admin app index.js file. We will change the title and body of the notification. At the end of the message payload, we will replace the token to the topic. That's all! Let's run the app on both Android and iOS devices. The application had launched on both devices. Let's try to send the topic notification by issuing the same command in the admin app terminal. You will see that both devices will receive the notification. Sending notification by topic allows us to broadcast messages to multiple devices at once. So far we only send notification without the data part. Notification without the data part is mainly used for displaying messages to end-user. This limits the capability of the push notification. Now, I am going to show you how to make use of the notification data part. We will enhance the dailyword topic notification we had created just now. Let's open the index.js under the admin app folder. In the message payload under the data section, we will add in two fields. The first field is the msgType. This field indicates the type of notification so that the mobile app knows how to handle the message. For now, we will set the msgType to "Search". This instructs the mobile app to perform a word definition lookup when the end-user tap on the received notification. The second field is the word field, it contains the word for the mobile app to perform the lookup via Oxford dictionary API. That's all for the admin app index.js file. Now, we need to modify the mobile app to respond accordingly to the received push notification. Let's define the logic first before we start coding. When the device received the dailyword notification with the msgType equal to "Search", the mobile app will navigate to the Search page and perform a word lookup via the Oxford dictionary API based on the word in the data part. Let's open the App.js in the JustCodeDict folder. We will import the pageActions require for the mobile app to perform the word lookup. We will also create the navigation reference as shown. The navigation reference is used to navigate the app to the search page regardless of which page the app is currently in. Scroll to the render method and add in the navigation reference in the NavigationContainer ref property. Without the navigation reference, the App class component will not be able to navigate within the app. It is because the App class component is not under any of the navigator components. Next, we will implement a method called forwardToSearchPage. This method will take in the word parameter and call the pageSearchSetUserWord action method to set the word in the Redux state. Then, it will use the navigation reference to navigate the app to the Search page and pass in a route parameter autoSeach to instruct the Search page to perform a word lookup without the user to press the Search button. Now, let's open the index.js under the src/screen/search folder. We first import the useRoute from React Navigation so that we can get the route parameter autoSeach. Scroll to the bottom of the file and we will use the useRoute hook to get the route and pass it into the ReduxSearch component as shown. Next, we will implement the componentDidUpdate method. In it, we will check if the autoSeach route parameter is defined or not. If it is defined and the value is true, then we will set it to false and perform a word lookup by invoking the onSearch method. That's all for the search index.js file. Back the App.js file, we will create a new method called processNotification method. The purpose of creating this method is to centralize the notification processing logic. Currently, we have four handlers to handle the notification, if we code the notification processing logic on each of the handle, it will be difficult for us to maintain the source code if we have more msgType notification to process. To be a good programmer, we don't just write code to get things to work. But also make our code efficient and easy to maintain. If you agreed with my viewpoint, please click on the Like button of this tutorial video. The processNotification method takes in the remoteMessage and fromBackground parameter. The remoteMessage is the received notification and the fromBackground parameter indicate if the notification is handled by the onNotificationOpenedApp or getInitialNotification handlers. At the beginning of the method, we will define the title, body, and alertBtns variables. Then we check if the remoteMessage is defined or not. We further check if remoteMessage notification part is defined or not. If defined, we will get the title and body as shown. Next, we will check the data part of remoteMessage is define or not. If defined, then we will check if the notification is handled by the background handler. If true, we create a switch statement to handle different msgType. For now, we only have one case which is the "Search". We will invoke the forwardToSearchPage method by passing in the word in the data part as the parameter so that the app will navigate to the Search page and perform a word lookup. Next, we will check if the notification is to be handled by the foreground app. If true, then we create a switch statement to handle different msgType. For now we also only have one switch case which is the "Search". In it, we will create two alert buttons in the array. The first button will invoke the forwardToSearchPage method similar to the background message. The second button will close the alert dialog box. The last part of the code is to check if the notification arrived when the app is in the foreground. If that is the case, then we need to display an alert dialog box with the title, body, and alert buttons defined above. Now, we need to invoke the processNotification method from the onMessage handler onNotificationOpenedApp handler and getInitialNotification handler. We had completed all the changes. Now, let's reload the application from all devices. Navigate the app to the Setting page. In the admin app terminal, issue the node index.js command to send the notification with data. We will see the mobile app will pop up an alert dialog box showing the title and body of the notification. When we tap on the View button, the app will navigate to the search page and perform the word lookup automatically. We had seen how a notification with data work when the mobile app is running in the foreground. Now, let us reload the app, navigate to the Setting page, and minimize the app on both devices. In the admin app terminal, issue the same command to send the notification with data again. You will see the device OS displayed the notification instead of the mobile app. Let's tap on the notification and we will see that the device will launch the app and navigate to the search page to perform the word lookup automatically. We had covered push notification with only notification part and with both notification and data part. However, do you know that we can create a "Silent" notification with only the data part? Let me show you how to use a "Silent" notification to inform the app user on the app update. Let's duplicate the index.js in the admin app folder and rename it as versionUpgrade.js. Open the versionUpgrade.js file, we will remove the entire notification part from the message payload. We will change the msgType to "VersionUpgrade". We replaced the word to nextVer with the value of 2. Then we specify the URL to update the app for both iOS and Android as shown. The link specified here will link to another app that I had developed previously. We will remove the android notification setting in the message payload and add in the priority setting to make the notification "Silent" in the Android device. We will also do the same for iOS by removing the sound in the aps payload. However, we need to specify a new setting called content-available with a value equal to 1 in the aps payload. Without this setting, the iOS device will not fire the setBackgroundMessageHandler and the message will not be processed as it is a Silent notification without UI. Last but not least we need to change the topic to "version_upgrade" in the message payload. We had completed the admin app portion. Now, we need to modify the mobile app to handle the version upgrade message. We need to install an npm module that allows the app to get its existing version info. Issue the yarn add react-native-version-number in the JustCodeDict terminal screen and press enter. The installation had completed. Let's open the index.js under the JustCodeDict folder. In the setBackgroundMessageHandler, we will check if the incoming message is for version upgrade or not. If it is, then we will save it into the device storage with the key nextVer. This allows the app to access the notification in the subsequent launch. Now, open the App.js file. We will create a method called checkVersionUpdate to check is there any version upgrade message in the device storage. If have, and the next version number is greater than the existing version number, then it will display an alert dialog box to inform the end-user about the version upgrade. When the user taps on the Update button, it will invoke the Linking.openURL method to redirect the user to the respective App or Play Store depending on the OS type. We will invoke checkVersionUpdate method in the componentDidMount method as shown. The checkVersionUpdate method is used to handle the version upgrade notification that reached the device when the app is not running or running in the background. Now, we also need to handle the version upgrade notification reached the device when the app is running in the foreground. To do that, let's scroll to the processNotification method. Under the switch statement that handles the foreground message, we will add in the new case "VersionUpgrade". In it, if the next version is greater than the existing version, then we will prepare the title, body, and action buttons for the alert dialog box similar to the checkVersionUpdate method. We had completed all the changes. Let's reload the application on both devices. Please take note that in iOS for the setBackgroundMessageHandler to work properly, we need to compile the app in the released configuration. The app had reloaded on both devices. We will first test the Silent notification when the app is running in the foreground. In the admin app terminal screen, let's issue the node versionUpgrade.js command. We will see the mobile app display an alert dialog box indicating there is a version upgrade. This dialog box is fired via the processNotification method. Tap on the Update button and you will see that the iOS device will launch the App Store and the Android device will launch the Play store. Now, let's quit the mobile app in both devices to test the Silent notification when the app is not running at all. In the admin app terminal screen, issue the same command again and press enter. We will wait for a few seconds to ensure the notification is delivered to the device as there is no notification bar at all. Now, let launch the app from the devices again and you will see the version upgrade dialog box. This dialog is fired via the checkVersionUpdate method instead of the processNotification method. Tap on the Update button and you will see the same effects. We had come to the end of this tutorial. Today, I had shown you how to enable and handle Push Notification within your app. I also had shown you how Push Notification can instruct the app to perform actions. Besides, I also had shown you how to send messages via the Firebase Console and the Firebase Admin SDK. For more information on the Firebase Admin SDK, please visit the firebase.google.com. And for more information on the React Native Firebase client SDK, please visit the rnfirebase.io. If you have any questions regarding this tutorial, please leave a comment below. You can follow the link to get the source code for this tutorial on our Github page. If you find our video useful, do support us by like our video, subscribe to our channel, and click on the notification bell! Thanks for watching, bye!
Info
Channel: Just Code
Views: 11,072
Rating: undefined out of 5
Keywords: android tutorial, apns, app development, apple, cloud function, cloud functions, cloud messaging, fcm, firebase, firebase cloud functions, firebase cloud messaging, firebase messaging app, firebase push notification, firebase realtime push notification, firestore chat, google, ios, messaging, notification-channel, push notification, push notification implementation, push notification tutorial, react native, react native firebase, mobile app development, rnfirebase
Id: wC3N-hxkWbk
Channel Id: undefined
Length: 43min 57sec (2637 seconds)
Published: Sat Jul 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.