使用 Firebase Cloud Messaging 推送通知
介绍
本教程将帮助您熟悉使用 Firebase 在 Android 项目中设置推送通知的基础知识。
Firebase 是服务器与接收您创建的推送通知的设备之间的一个模块。您的服务器通知 Firebase 必须发送通知。然后 Firebase 在后台完成工作以发布通知。
为了与 Firebase 建立连接,您需要在Firebase 控制台中为自己的应用创建一个项目。您必须以这样的方式设置您的项目,即每次用户安装它时,他们的设备都会使用唯一的令牌在 Firebase 中注册。虽然这看起来很复杂,但设置实际上很简单。
创建 Firebase 项目
前往Firebase 控制台,登录并创建一个新的Android项目。系统将要求您输入包名称。您可以在项目中几乎每个 Java 文件的顶部找到包名称。您也可以在AndroidManifest.xml文件中找到它。(您还可以添加 SHA1 密钥以采取额外的安全措施,但本教程不需要这样做。)
接下来,您将获得一个google-services.json文件,其中包含有关您的项目签名的信息。如果您在创建应用程序时错过了说明,则需要将此文件添加到您的应用程序目录中,当您将文件结构打开到 Project 时,您可以找到它。
之后,您需要在项目级build.gradle文件中添加gms依赖项:
buildscript {
dependencies {
// Add this line
classpath 'com.google.gms:google-services:3.0.0'
}
}
然后,在应用级build.gradle中添加相应的插件。您还需要在此文件中添加 Firebase 消息传递依赖项。
dependencies {
compile 'com.google.firebase:firebase-messaging:10.2.1'
}
// Bottom of your file
apply plugin: 'com.google.gms.google-services'
请注意,firebase-messaging依赖项必须与其他 gms 库的版本相同。否则,您的应用很可能会无法注册设备并获取 Firebase 令牌。应用程序甚至更有可能无法编译,因为它找不到您即将实现的 Firebase 类。
创建 Firebase 服务
下一步是创建两个服务。一个服务负责处理设备注册过程,另一个服务负责接收实际通知。
转到您的AndroidManifest.xml文件并在应用程序标签下添加以下服务声明:
<service
android:name=".notifications.MyFirebaseMessagingService"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name=".notifications.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
在同一标签下,您还可以添加默认通知值的元数据,但这不是强制性的:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@mipmap/ic_launcher" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorTransparent" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
您需要添加到清单文件的最后一件事是接收权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
设置服务
接下来,继续在名为notifications的新包中创建您在清单中声明的两个Java类服务。
这是MyFirebaseInstanceIDService类的实现:
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import co.centroida.notifications.Constants;
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
@Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
preferences.edit().putString(Constants.FIREBASE_TOKEN, refreshedToken).apply();
}
}
这项服务的目的非常简单:
它获取Firebase Token,从而建立设备与 Firebase 之间的连接。通过此令牌,您可以向此特定设备发送通知。获取后,此令牌将保存在共享首选项中以供将来使用。自然,您希望在某个时间点(例如用户注册)将其发送到您的服务器,甚至立即将其发送到您的服务器,以便服务器可以通过 Firebase 向此设备发送通知。
继续讨论更有趣的类,即MyFirebaseMessagingService。
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
}
}
此服务需要扩展 FirebaseMessagingService。当目标设备收到通知时,会调用onMessageReceived。您手中已经有了remoteMessage对象,其中包含您收到的有关通知的所有信息。现在让我们使用该信息创建一个实际通知。
@Override public void onMessageReceived(RemoteMessage remoteMessage) {
notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//Setting up Notification channels for android O and above
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
setupChannels();
}
int notificationId = new Random().nextInt(60000);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification_small) //a resource for your custom small icon
.setContentTitle(remoteMessage.getData().get("title")) //the "title" value you sent in your notification
.setContentText(remoteMessage.getData().get("message")) //ditto
.setAutoCancel(true) //dismisses the notification on click
.setSound(defaultSoundUri);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationId /* ID of notification */, notificationBuilder.build());
}
在这里,为了每次收到新消息时都能获得唯一的通知,为了便于举例,我们生成一个随机数并将其用作通知 ID。使用此 ID,您可以对通知执行多项操作。因此,如果它们是同一类型,您可能应该将它们分组,或者更新它们。如果您想单独查看每个通知,则它们的 ID 需要不同。
Android Oreo 兼容性
每个针对 SDK 26 或更高版本(Android O)的应用都必须实现通知渠道并将其通知添加到其中至少一个。我不会详细介绍它们的工作原理,因为这超出了本文的范围。简而言之,您可以根据通知的功能和重要性级别将其分为多个渠道。拥有更多渠道可以让用户更好地控制他们收到的通知。您可以在此处阅读有关渠道的更多信息。如果您希望最新的手机能够接收您的任何通知,请将此方法粘贴到您的服务中。
@RequiresApi(api = Build.VERSION_CODES.O)
private void setupChannels(){
CharSequence adminChannelName = getString(R.string.notifications_admin_channel_name);
String adminChannelDescription = getString(R.string.notifications_admin_channel_description);
NotificationChannel adminChannel;
adminChannel = new NotificationChannel(ADMIN_CHANNEL_ID, adminChannelName, NotificationManager.IMPORTANCE_LOW);
adminChannel.setDescription(adminChannelDescription);
adminChannel.enableLights(true);
adminChannel.setLightColor(Color.RED);
adminChannel.enableVibration(true);
if (notificationManager != null) {
notificationManager.createNotificationChannel(adminChannel);
}
}
我已初始化一个常量ADMIN_CHANNEL_ID,其类型为String。我使用该 id 变量来引用我新创建的频道。因此,每次我使用NotificationCompat.Builder创建新通知时,我都会初始化构建器对象并在构造函数中传入 id,如下所示:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, ADMIN_CHANNEL_ID) {...}
后台兼容性
另外需要注意的是,我们使用remoteMessage.getData()来访问收到的通知的值。现在,Firebase 通知有两种类型 - 数据消息和通知消息。
无论应用程序是在前台还是后台,数据消息都会在onMessageReceived中处理。但是,只有当应用程序在前台时才会收到通知消息,这让它们变得有点无用,或者至少有点无聊,你不觉得吗?
对于统一的通知系统,我们使用仅包含数据负载的消息。
包含通知和数据有效负载的消息被视为通知消息,因此当应用程序处于后台时,它们不会被MyFirebaseMessagingService处理!
如果您尚未设置服务器,您仍然可以使用POST http 请求直接向 Firebase 测试推送通知。您可以使用任何您认为合适的应用程序,我们使用 Google Postman插件。您可以从此链接下载它。
您可以从 firebase 使用的端点是这个:https://fcm.googleapis.com/fcm/send
获取服务器密钥:
此请求需要一个授权标头,其值是Firebase 中应用程序的<strong
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~