内容简介:Firebase Cloud Messaging (FCM) is a set of tools that sends push notifications and small messages of up to 4 KB to different platforms: Android, iOS and web.This topic is useful because you use push notifications in a lot of mobile projects. Firebase is on
Firebase Cloud Messaging (FCM) is a set of tools that sends push notifications and small messages of up to 4 KB to different platforms: Android, iOS and web.
This topic is useful because you use push notifications in a lot of mobile projects. Firebase is one of the simplest methods to get notifications working.
In this project, you’ll build Drink-it , an app that sends push notifications throughout the day reminding you to stay hydrated. After all, with our busy lives, many of us forget how important water is.
In the process you’ll learn:
- How to set up Firebase and create a project in it.
- A method to connect your mobile app with the Firebase console.
- The difference between receiving messages in the foreground and background of your app.
- How to use the data received in the messages.
- How to send test messages through Firebase console.
Note : This Firebase Cloud Messaging Tutorial assumes you know the basics of Android development, Kotlin and Android Studio. Also, it assumes that you already have a Google Account to configure the Firebase console. If you’re new to Android development, check out our Kotlin for Android Introduction or our Beginning Android Development With Kotlin series.
Getting Started
Download the starter project by clicking on the Download Materials button at the top or bottom of the tutorial. Open the starter project in Android Studio 3.6 or later.
Looking at the code, you’ll notice the starter project provides the user interface and some classes where you’ll add the logic of the app.
Build and run the starter project. You’ll see the Drink-It app with a button for retrieving a token. Right now, the button does nothing, but you’ll configure it soon.
What Is Firebase Cloud Messaging?
Push notifications — those small alerts that slide in from the top of our screen, letting us know an app needs our attention — have been around since the early days of Android apps. There are many tools that can help us add this functionality, but Firebase Cloud Messaging is one of the easiest and most straightforward to add in your projects.
Firebase Cloud Messaging has a simple architecture with four main parts:
- A service, API or console that sends messages to targeted devices.
- The Firebase Cloud Messaging back end, where all the processing happens.
- A transport layer that’s specific to each platform. In Android’s case, this is called the Android Transport Layer .
- The SDK on the device where you’ll receive the messages. In this case, called the Android Firebase Cloud Messaging SDK.
You’ll use each of these parts throughout the tutorial. First, you’ll look at the setting up Drink-It in the Firebase console.
Configuring the Project in the Console
Before receiving any push notifications in your app, there’s a series of steps you’ll need to configure in the Firebase console. That’s what you’ll do in the first part of the tutorial.
Creating a Firebase Project in the Console
To begin, sign in to the Firebase console . Make sure you use the Google account you want to tie to your project.
After logging in, you’ll see one of two options:
- If this is your first project, you’ll see a button with the label Create a project .
- If you’ve already started other projects, you’ll see a list of them and a button with the label Add project.
Once you get to the next screen, name the project and accept the terms of service. You can choose whatever name you want since you only need it to identify the project.
For this tutorial, you’ll set the name to Drink-It . Once the name is set, accept the Firebase terms and click continue.
The next screen will prompt you to add Google Analytics. Click the checkbox to get statistics about your notifications, like how many people received them, if they opened them and more.
Analytics aren’t required for this tutorial, but you can activate them if you’re interested.
Finally, click Create project and wait until it says it’s ready. You’ll see an image like the one shown below.
Congratulations, you just created a Firebase project that works for Android, iOS and web!
Registering the App With Firebase
Now, you’ll continue to configure your Android app. Once the Firebase project is ready. Click Continue to display the main screen of the project.
Once on the project home page, you’ll notice several options and details. Here’s where you’ll find the option to add Firebase to an app.
To start integrating Firebase with your project, click the Android button, which is under Get started by adding Firebase to your app . You’ll see a screen requesting data from your app.
Enter the following information:
- Android Package Name: com.raywenderlich.android.drinkit . This is important. It must match your application ID.
- App Nickname: Drink-it .
- Debug signing certificate SHA-1: You don’t need this, just leave it empty.
Next, click Register app to proceed to the next step.
Adding Firebase Configuration Files to Your Android Project
This screen prompts you to download a JSON file that contains the service configuration for Firebase. Save it anywhere on your computer and remember where you place it. You’ll add it to the project next.
Go into Android Studio and switch to the project view in the left panel:
Add the file to the project in the path DrinkIt/app :
Note : Your starter project already contains a file named google-services.json , but you still need to replace it with the one you just downloaded. The starter project includes this file so Android Studio can compile and run the starter project at this initial stage. When you start your own app from scratch, you won’t have this file in the project folder.
Adding the Firebase SDK to the App
In Android Studio, switch back to the Android view in the left panel:
Open build.gradle , which Android Studio tags as (Project: DrinkIt) . This file is in Gradle Scripts/build.gradle .
Next, add this code in the dependencies section:
classpath 'com.google.gms:google-services:4.3.3'
Click Sync Now in the yellow warning at the top and wait for the Gradle sync.
The project build should be successful.
Then open Build.gradle , labeled as (Module: app) . This file is also in the Gradle Scripts section within the Android view.
Next, add this code at the top with the other, similar lines:
apply plugin: 'com.google.gms.google-services'
If you chose the Google Analytics option during the Firebase project creation, add this in the dependencies section:
implementation 'com.google.firebase:firebase-analytics:17.2.3'
Once again, click Sync Now and wait for the build to finish.
Go back to the Firebase console and click Next in the screen where you downloaded the file. You’ll see a small prompt that checks whether your app has connected to the server or not:
Build and run to make this check successful. The app will look like the image below with no changes in the UI:
If the check was successful, the yellow warning will change to a congratulations message:
If everything is correct, click Continue to console . Otherwise, go back over the steps above and check you did everything correctly.
You’ll now see the console homepage and the Android logo:
Build and run. You shouldn’t see any changes in the app.
Configuring the Demo App
At this point, you’ve done all the configuration you need to do in the Firebase console. Next, you’ll add some code to the Drink-it app so it can remind you to drink water! If you haven’t had any recently, you can take a drink right now, by the way. :]
Including the Maven Repository
Google recommends adding their Maven repository to your app, but all Android Studio 3.6 projects include it by default. Take a moment to ensure this repository isn’t missing.
In your project-level build.gradle file — labeled Project: DrinkIt in Android Studio — make sure you have a line of code with google()
in the repositories
section of buildscript
and allprojects
respectively.
Next, you need to edit the Android Manifest.
Open AndroidManifest.xml in app/manifests . Inside the application
tags, add the following:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
The code above adds a service for handling the received notifications. Within the project, you have a file called MyFirebaseMessagingService in com.raywenderlich.android.drinkit
. That service is currently empty, but once you complete it later, it will take care of receiving and processing your notification information.
For now, open MyFirebaseMessagingService and make sure it extends from FirebaseMessagingService
as shown below:
class MyFirebaseMessagingService : FirebaseMessagingService() {
Next, you need to add the following dependency in your app module build.gradle :
implementation 'com.google.firebase:firebase-messaging:20.1.3'
This dependency includes the sources for FirebaseMessagingService
. However, you still need to add the following import on the top of MyFirebaseMessagingService :
import com.google.firebase.messaging.FirebaseMessagingService
Using the Device Token
The device token is a unique identifier that contains two things:
- Which device will receive the notification.
- The app within that device that will receive the notification.
Firebase automatically generates these tokens and delivers them to you as a developer.
Retrieving the Device Token
Device tokens may change over time, due to circumstances like:
- The app deleted the Instance ID.
- The user got a new device and restored the app.
- The user uninstalled and reinstalled the app.
- The user cleared app data.
In these cases, you’ll need to retrieve the device token.
In most of your apps, you’ll retrieve this token in the background. Sometimes, you’ll need to save it to a database so you can use it to send push notifications with internal APIs. In this app, you already have a Retrieve token button, which you’ll use so you can see the operation’s result.
Open MainActivity.kt . In the layout of this screen, there’s a Retrieve token button. Create an onClickListener
for the button inside onCreate()
by using the following code:
button_retrieve_token.setOnClickListener { // 1 FirebaseInstanceId.getInstance().instanceId .addOnCompleteListener(OnCompleteListener { task -> // 2 if (!task.isSuccessful) { Log.w(TAG, "getInstanceId failed", task.exception) return@OnCompleteListener } // 3 val token = task.result?.token // 4 val msg = getString(R.string.token_prefix, token) Log.d(TAG, msg) Toast.makeText(baseContext, msg, Toast.LENGTH_LONG).show() }) } }
Here’s what this code does, step-by-step:
- You get the instance of the app that’s tied to the Firebase back end and add a complete listener to it so you know when the task finishes, whether with an error or success.
- You check if the task, which is the result of this function, isn’t successful and return an error to the console.
- If the task is successful, you get the result from it.
- After getting the token, you set it as a string and output it for both the terminal and a toast message.
The code shows several errors now because you need to import some classes. To fix those errors, add this code to the top of MainActivity.kt with the rest of the imports:
import com.google.firebase.iid.FirebaseInstanceId import com.google.android.gms.tasks.OnCompleteListener import android.util.Log import android.widget.Toast
Build and run, then tap the Retrieve token button. The token now shows in the toast message. Check the console and you’ll also see the token there.
With the device token retrieved, Firebase can now connect with your device. In the next section, you’ll see how to do that shortly.
Checking if Devices Can Receive Notifications
When sending push notifications in Android, it’s important to make sure the devices you’re pushing to have Google Play Services enabled. Otherwise, they won’t be able to receive your messages.
In a small app, sending push notification to some devices that can’t receive them might not matter. However, when you’re using resources on a paid quota, distinguishing the devices that can get messages from the ones that can’t is vital.
To do this, add this function in MainActivity.kt :
private fun checkGooglePlayServices(): Boolean { // 1 val status = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) // 2 return if (status != ConnectionResult.SUCCESS) { Log.e(TAG, "Error") // ask user to update google play services and manage the error. false } else { // 3 Log.i(TAG, "Google play services updated") true } }
Check out what this code does:
- First, you use Android’s availability API to check for Google Play Services.
- If the status isn’t successful, you need to manage the error. In this case, you know the user can’t receive push notifications.
- If it is successful, there’s no problem and you can continue with the notification process.
Again, you’ll get errors because of missing imports. Add those imports at the top of the file with this code:
import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability
Now, use the following code to add the check to onClickListener
, right after button_retrieve_token.setOnClickListener {
:
if (checkGooglePlayServices()) { } else { //You won't be able to send notifications to this device Log.w(TAG, "Device doesn't have google play services") }
Depending on the purpose of your notifications, you may want to display an alert message to the user. For this app, you’ll just show the message in the terminal.
Test this error by creating an Android Virtual Device with Google Play Services disabled. Notice that the screen has a message suggesting that you use another image. That’s because most app dependencies use Google Play Services.
Build and run. You should see no change in the app.
Sending a Test Message With Notification Composer
Firebase includes a tool called Notification Composer that lets you send tests or custom messages when your user base isn’t too big. For larger projects, you’ll need to create an API or another tool to automate this process.
Either way, it’s important to learn to use this tool, because it’s always handy to be able to send messages for testing.
To access the Notification Composer in the Firebase console, click the project name.
Since the project is new, you’ll find the option to Send your first message .
If you don’t have this option available, you can find it on the left side menu under the grow section:
Configuring Notification Composer
Notification Composer allows you to configure the data of the message you’ll send and preview your notification on the right side of the window. Enter the following data:
- Notification title : Most apps use the name of the app, but you can actually add any title.
- Notification text : Add: “This is a reminder to drink water!”
- Notification image : This is optional. For this tutorial, you won’t add an image.
- Notification name : This is for your personal use, so you can identify the notification in the console. This data is also optional.
Note that the notification text can be anything you want, but it should be brief or the entire message won’t display.
Now, select your app identifier: com.raywenderlich.android.drinkit
You can schedule the time, but for this tutorial select now — unless you want to wait for it to arrive!
You can play around with the other values, but they aren’t necessary. When you’re done, click Review .
A confirmation window will appear. If you didn’t activate Google Analytics, you’ll see a red alert. Don’t worry about it, it’s not required.
Click Publish and take a look at the emulator or device where you installed your app.
If you’re in the list of notifications, you can either click the New notification button or select the Duplicate notification option from the drop-down menu to send another one.
Be careful! If the app is in the foreground, you won’t see the notification. Later, you’ll configure foreground notifications.
For now, send the app to the background and try again, and you’ll see a notification appear.
When you click on the notification, it will open the app. Nothing happens because you haven’t configured any additional actions.
Background-Restricted Apps
If for some reason your notification isn’t appearing. It could be because of the version of Android your device is using. Android 9, also known as Android P, introduced the possibility of restricting apps from running in the background. Although you’re probably testing on an emulator or on your own device, it’s important to know this is possible.
If you have trouble testing, check that the app isn’t background-restricted.
To access these settings, go to Settings ▸ Apps & notifications , select the Drink it app from the list then scroll down and select Battery . You might need to open the Advanced section before you see the Battery option.
Once in the Battery usage screen, tap on Background restriction . You’ll get a warning that notifications may arrive later or not arrive at all.
If your notification shows up without problems, you’re good to carry on to the next section.
Setting Custom Icons and Colors
Android gives you the possibility to set a custom icon and color for the notifications through Android Manifest.
There are several ways to set the notification’s icon:
- Don’t assign an icon. In this case, the app icon will appear.
- Set it in Android Manifest.
- Send it in the notification payload.
The color of the notification will vary depending on the Android version. If the version is earlier than Android N, the color will appear in the background of the icon. If the version is N or above, the icon and app name will use the color.
You’ll set the color and icon using Android Manifest. Add the following code to AndroidManifest.xml inside of the application
tag:
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_launcher_foreground" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorPrimary" />
The first tag sets the notification icon; the second sets the color. The name values are standard, so every time you want to change the icon or color, you’ll add the same value to the name attribute. The resource value is the one you’ll configure. For the icon, it can have any drawable and for the color, any valid value is possible.
Build and run, then send another notification. It will use the color and icon you selected, which may vary depending on the device or emulator you’re using.
Receiving Notifications in the Foreground Versus Background
When receiving notifications, it’s important to distinguish whether the app is running on the foreground or background. Basically, you need to consider the following:
- Foreground : The notification and the data are both handled in
onMessageReceived()
. - Background : The System UI handles the notification, while
onMessageReceived()
handles the data payload.
You’ll now configure Drink-it to handle notifications when it’s running in the foreground.
Add the following code to MyFirebaseMessagingService
:
override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) handleMessage(remoteMessage) }
Then you’ll add another method for handling the message:
private fun handleMessage(remoteMessage: RemoteMessage) { //1 val handler = Handler(Looper.getMainLooper()) //2 handler.post(Runnable { Toast.makeText(baseContext, getString(R.string.handle_notification_now), Toast.LENGTH_LONG).show() } ) }
Now, review the code above:
- You create a handler to get the message and extract the data.
- You use that handler to post the toast through a runnable .
You’ll get errors because of missing imports. Add them at the top of the file with this code:
import android.os.Handler import android.os.Looper import android.widget.Toast import com.google.firebase.messaging.RemoteMessage
Build and run and check the notification with the app in the foreground.
Displaying Notification Data in Activities
Sometimes, you want to do something with the data that arrived through the notification. For your last step, you want to display the text of the notification in the activity.
To do this, you’ll add a broadcast manager , which listens to incoming data from notifications and does the appropriate treatment.
To start, add this code to MyFirebaseMessagingService :
private var broadcaster: LocalBroadcastManager? = null override fun onCreate() { broadcaster = LocalBroadcastManager.getInstance(this) }
Then add this code to handleMessage()
, inside handle.post
:
remoteMessage.notification?.let { val intent = Intent("MyData") intent.putExtra("message", it.body); broadcaster?.sendBroadcast(intent); }
If you see an error on the intent, import this code at the top:
import android.content.Intent
In MainActivity.kt , you need to add some more code to receive the message. First, add a BroadcastReceiver
with the following code:
private val messageReceiver: BroadcastReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent) { text_view_notification.text = intent.extras?.getString("message") } }
This BroadcastReceiver
checks the notification when it arrives and looks for the string called message
. It then puts it on the screen, assigning it to notification_text
.
If you have errors, it’s because you need to import some more classes. Add this at the top of your file:
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent
Next, in the activity, add this code to OnStart()
:
LocalBroadcastManager.getInstance(this).registerReceiver(messageReceiver, IntentFilter("MyData"))
With the code above, you create the broadcast manager instance so whenever a notification arrives, you check if the data labeled MyData
is available.
Then, add this code to OnStop()
:
LocalBroadcastManager.getInstance(this).unregisterReceiver(messageReceiver)
With this code, you’ll unregister this receiver to avoid keeping it in memory when it’s no longer needed.
You also need to import the context, as some of the added code may show errors. Add this to your imports:
import androidx.localbroadcastmanager.content.LocalBroadcastManager import android.content.IntentFilter
Build, run and send a notification. You’re now receiving the notifications correctly! Check the image below to compare your code:
Sending a Payload in the Notification
You have one last step to implement. If you close the app completely and send the notification, you’ll get it in the System UI. However, if you click it, the text on the screen is still Drink It and not the text of the notification.
To fix this, you need to modify the code in MyFirebaseMessagingService.kt . In handler.post
, change the code in remoteMessage.notification
to the following:
remoteMessage.notification?.let { val intent = Intent("MyData") intent.putExtra("message", remoteMessage.data["text"]); broadcaster?.sendBroadcast(intent); }
This takes the information that comes in the payload of the notification with the key text
and puts it in an intent called MyData
with another key called message
, which is directed to MainActivity .
To receive this, add this code to the onCreate()
of your MainActivity
:
val bundle = intent.extras if (bundle != null) { text_view_notification.text = bundle.getString("text") }
With this, you’re displaying the content of the notification payload in text_view_notification
.
Now, test that this works. Create a notification in Firebase Notification Composer as you did in the previous steps. This time, however, use the following configuration options in step 5 of the wizard.
In the key field, enter text . Then, in the value textfield, enter I know you haven’t finished your water bottle! .
Build and run, then send this notification and voila! Everything works now.
Test it in background and foreground and make sure the text view changes with the message received. This is how the app should look now:
Congratulations! You just created an Android app that reminds you to drink water. Just remember to schedule your notifications in Firebase Composer so they arrive regularly. Don’t forget to keep hydrated. :]
Where to Go From Here?
Download the completed project files by using the Download Materials button at the top or bottom of the tutorial.
If you want to learn more about Firebase for Android, check out our tutorial onReal-Time Databases or our tutorial on Authentication with Firebase .
We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。