Firebase Cloud Messaging是一种实时解决方案,无需任何费用即可将通知发送到客户端应用程序。 FCM可以可靠地传输高达4Kb负载的通知。在本文中,开发了一个示例应用程序,显示了如何使用此服务。尽管FCM还允许使用应用服务器发送通知,但此处使用Firebase admin SDK。请按照整篇文章实施FCM示例。
方法
第1步:将Firebase添加到项目中并获得所需的权限
要将Firebase添加到项目中,请参阅将Firebase添加到Android App。以下是将FCM添加到应用程序的要点。转到工具-> Firebase->云消息传递->设置Firebase Cloud Messaging
- 将您的应用程序连接到Firebase:完成创建Firebase项目的三个步骤。
- 将FCM添加到应用程序。
由于接收FCM通知需要使用Internet,因此请在 application>和 manifest>标记之间的任何位置向AndroidManifest.xml文件添加以下权限。
Note:
compile ‘…..’
this format for setting up dependencies is deprecated, instead, use
implementation ‘…..’
to declare dependencies in case of any discrepancy.
步骤2:添加所有必需的可绘制资源
在这里,以下图标已用作可绘制资源。将所有可绘制资源添加到可绘制资源文件夹中。
步骤3:自定义activity_main.xml
在此,应用程序的主屏幕仅包含一个TextView,但是,可以根据要求自定义应用程序。
activity_main.xml
notification.xml
AndroidManifest.xml
AndroidManifest.xml
FirebaseMessageReceiver.java
package com.example.fcmnotfication_gfg;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;
import androidx.core.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseMessageReceiver
extends FirebaseMessagingService {
// Override onMessageReceived() method to extract the
// title and
// body from the message passed in FCM
@Override
public void
onMessageReceived(RemoteMessage remoteMessage) {
// First case when notifications are received via
// data event
// Here, 'title' and 'message' are the assumed names
// of JSON
// attributes. Since here we do not have any data
// payload, This section is commented out. It is
// here only for reference purposes.
/*if(remoteMessage.getData().size()>0){
showNotification(remoteMessage.getData().get("title"),
remoteMessage.getData().get("message"));
}*/
// Second case when notification payload is
// received.
if (remoteMessage.getNotification() != null) {
// Since the notification is received directly from
// FCM, the title and the body can be fetched
// directly as below.
showNotification(
remoteMessage.getNotification().getTitle(),
remoteMessage.getNotification().getBody());
}
}
// Method to get the custom Design for the display of
// notification.
private RemoteViews getCustomDesign(String title,
String message) {
RemoteViews remoteViews = new RemoteViews(
getApplicationContext().getPackageName(),
R.layout.notification);
remoteViews.setTextViewText(R.id.title, title);
remoteViews.setTextViewText(R.id.message, message);
remoteViews.setImageViewResource(R.id.icon,
R.drawable.gfg);
return remoteViews;
}
// Method to display the notifications
public void showNotification(String title,
String message) {
// Pass the intent to switch to the MainActivity
Intent intent
= new Intent(this, MainActivity.class);
// Assign channel ID
String channel_id = "notification_channel";
// Here FLAG_ACTIVITY_CLEAR_TOP flag is set to clear
// the activities present in the activity stack,
// on the top of the Activity that is to be launched
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Pass the intent to PendingIntent to start the
// next Activity
PendingIntent pendingIntent
= PendingIntent.getActivity(
this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
// Create a Builder object using NotificationCompat
// class. This will allow control over all the flags
NotificationCompat.Builder builder
= new NotificationCompat
.Builder(getApplicationContext(),
channel_id)
.setSmallIcon(R.drawable.gfg)
.setAutoCancel(true)
.setVibrate(new long[]{1000, 1000, 1000,
1000, 1000})
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent);
// A customized design for the notification can be
// set only for Android versions 4.1 and above. Thus
// condition for the same is checked here.
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.JELLY_BEAN) {
builder = builder.setContent(
getCustomDesign(title, message));
} // If Android Version is lower than Jelly Beans,
// customized layout cannot be used and thus the
// layout is set as follows
else {
builder = builder.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.gfg);
}
// Create an object of NotificationManager class to
// notify the
// user of events that happen in the background.
NotificationManager notificationManager
= (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
// Check if the Android Version is greater than Oreo
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel
= new NotificationChannel(
channel_id, "web_app",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(
notificationChannel);
}
notificationManager.notify(0, builder.build());
}
}
MainActivity.java
package com.example.fcmnotfication_gfg;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
步骤4:创建通知布局
创建一个新的notification.xml文件,以设计Notification的布局。之所以说此步骤为可选步骤,是因为也可以直接设置内容和标题,而无需自定义通知的外观,但是,此处的通知具有以下布局。此处的通知包括:
- ImageView
- 标题的TextView
- 消息的TextView。
notification.xml
步骤5:创建消息接收类
创建一个FirebaseMessageReceiver。 Java类。此类扩展了FirebaseMessagingService。将以下代码添加到 activity>和 application>标签之间的AndroidManifest.xml文件中,以将FirebaseMessagingService识别为应用程序中的服务。
AndroidManifest.xml
在这里,为属性“ android:name”分配了扩展FirebaseMessagingService的Java文件的名称,因此请传递类名FirebaseMessageReceiver 。客户端应用程序在后台运行时,除了接收通知之外,此服务还需要执行任何类型的消息处理。它还可用于在前台应用程序中接收通知等。完整的AndroidManifest.xml文件在下面给出。
AndroidManifest.xml
第6步:使用FirebaseMessageReceiver。 Java类
FirebaseMessageReceiver。 Java类重写onMessageReceived()
方法来处理2个事件:
- 如果Notification包含任何数据有效负载,即从应用服务器接收到的数据有效负载。
- 如果Notification包含任何通知有效负载,即通过Firebase Admin SDK发送。
此方法将RemoteMessage作为参数。 RemoteMessage是扩展对象类并实现Parcelable接口的类。它不过是使用FCM传递的消息的对象。然后,上述方法调用用户定义的方法showNotification()
,该方法又接受两个参数。通过代码本身的注释提供了详细的说明。大于Oreo的Android版本中的通知需要一个通知渠道。
在此示例中,由于设计了自定义通知,因此定义并调用了方法getCustomDesign()
来相应地设置资源。此方法设置用于显示接收到的通知的自定义布局。假设仅从通知中接收到标题和正文,它将根据ID适当地映射TextView ,并设置通知的图像资源。该文件的完整代码如下。
FirebaseMessageReceiver。Java
package com.example.fcmnotfication_gfg;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.widget.RemoteViews;
import androidx.core.app.NotificationCompat;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FirebaseMessageReceiver
extends FirebaseMessagingService {
// Override onMessageReceived() method to extract the
// title and
// body from the message passed in FCM
@Override
public void
onMessageReceived(RemoteMessage remoteMessage) {
// First case when notifications are received via
// data event
// Here, 'title' and 'message' are the assumed names
// of JSON
// attributes. Since here we do not have any data
// payload, This section is commented out. It is
// here only for reference purposes.
/*if(remoteMessage.getData().size()>0){
showNotification(remoteMessage.getData().get("title"),
remoteMessage.getData().get("message"));
}*/
// Second case when notification payload is
// received.
if (remoteMessage.getNotification() != null) {
// Since the notification is received directly from
// FCM, the title and the body can be fetched
// directly as below.
showNotification(
remoteMessage.getNotification().getTitle(),
remoteMessage.getNotification().getBody());
}
}
// Method to get the custom Design for the display of
// notification.
private RemoteViews getCustomDesign(String title,
String message) {
RemoteViews remoteViews = new RemoteViews(
getApplicationContext().getPackageName(),
R.layout.notification);
remoteViews.setTextViewText(R.id.title, title);
remoteViews.setTextViewText(R.id.message, message);
remoteViews.setImageViewResource(R.id.icon,
R.drawable.gfg);
return remoteViews;
}
// Method to display the notifications
public void showNotification(String title,
String message) {
// Pass the intent to switch to the MainActivity
Intent intent
= new Intent(this, MainActivity.class);
// Assign channel ID
String channel_id = "notification_channel";
// Here FLAG_ACTIVITY_CLEAR_TOP flag is set to clear
// the activities present in the activity stack,
// on the top of the Activity that is to be launched
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Pass the intent to PendingIntent to start the
// next Activity
PendingIntent pendingIntent
= PendingIntent.getActivity(
this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
// Create a Builder object using NotificationCompat
// class. This will allow control over all the flags
NotificationCompat.Builder builder
= new NotificationCompat
.Builder(getApplicationContext(),
channel_id)
.setSmallIcon(R.drawable.gfg)
.setAutoCancel(true)
.setVibrate(new long[]{1000, 1000, 1000,
1000, 1000})
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent);
// A customized design for the notification can be
// set only for Android versions 4.1 and above. Thus
// condition for the same is checked here.
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.JELLY_BEAN) {
builder = builder.setContent(
getCustomDesign(title, message));
} // If Android Version is lower than Jelly Beans,
// customized layout cannot be used and thus the
// layout is set as follows
else {
builder = builder.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.drawable.gfg);
}
// Create an object of NotificationManager class to
// notify the
// user of events that happen in the background.
NotificationManager notificationManager
= (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
// Check if the Android Version is greater than Oreo
if (Build.VERSION.SDK_INT
>= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel
= new NotificationChannel(
channel_id, "web_app",
NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(
notificationChannel);
}
notificationManager.notify(0, builder.build());
}
}
Note: The notification when clicked will always redirect to the launcher activity of the app when the app is in the background and to the activity passed in the intent if it is in the foreground. To redirect the user always to some other activity than the launcher, you’ll have to send data payload using a server app, sending messaging using Firebase SDK does not support this.
步骤7:完成MainActivity。 Java文件
由于在这里activity_main.xml中没有提供太多内容,因此MainActivity文件不需要任何其他代码。
主要活动。Java
package com.example.fcmnotfication_gfg;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
现在,在您的模拟器或移动设备上运行该应用程序。
步骤8:使用FCM发送通知
- 转到Firebase控制台,然后选择适当的项目。
- 选择“云消息传递” 。
- 选择发送您的第一条消息。弹出以下窗口。填写详细信息。文本字段是强制性的,其余全部是可选的。您也可以使用链接添加图片或上传图片,但是上传图片会产生额外的存储费用。
- 在目标部分中,选择应用程序域。
- 可以立即发送通知,也可以安排将来的某个时间。
- 其余所有其他字段均为可选,可以保留为空。单击“查看” ,然后单击“发布” 。