收到 Firebase 通知后打开应用程序(FCM)

45

我希望能在收到通知时自动打开应用程序,使用 Firebase 和新的 FCM 通知是否可以实现?

我知道可以设置 click_action,但那只是为了自定义点击通知后启动哪个活动,我需要一些东西,可以在收到通知时自动启动。

我尝试了 Firebase 的快速入门消息示例,它有一个 onMessageReceived() 方法,但如果应用程序在前台,它才起作用。是否有某些东西也可以在应用程序处于后台时执行? GCM 可以通过直接从广播接收器中启动活动意图来完成我想要的功能,当收到通知时会调用该广播接收器。


1
如果您再次阅读文档,您会发现当负载中没有通知标签时,onMessageReceived仅在后台调用。 - tyczj
但是我尝试添加了一个启动意图,startActivity甚至没有被调用。 - stevyhacker
如果您在这里看,您将会看到 onMessageReceived 被调用并且它写入了 foreground。https://firebase.google.com/docs/cloud-messaging/downstream#sample-receive - stevyhacker
检查我的答案,也许你会有一个想法:https://dev59.com/cJjga4cB1Zd3GeqPDwDS#37843845 - Hisham Muneer
请查看此链接 https://stackoverflow.com/a/44800598/7329597,希望您能找到并获得您需要的答案。 - Sejal Baraiya
我也在寻找解决方案。 - tuledev
4个回答

66

快速回答:

要通过 FCM 自动打开应用程序,您需要使用 data-message,它保证始终调用 FirebaseMessagingService.onMessageReceived() 方法。

然后,您可以在 .onMessageReceived() 方法中添加逻辑来启动首选活动。

警告:在大多数应用程序中,无需任何用户交互即可启动 UI 是一种非常糟糕的做法!请阅读此处的 MarkG 答案: 如何从服务启动 Activity?

[...] 打断用户当前正在进行的操作被认为是不好的设计形式,特别是来自应该在后台运行的东西。
因此,您应该考虑使用通知 [...] 在用户决定调查时启动所需的 Activity。 [...]

完整解释:

FCM 的工作方式类似于 GCM,并且可以接收两种类型的消息:

  1. 显示消息:
    有效载荷{"notification" : { "body" : "hello world"}}
    这些消息在应用程序在后台运行时自动显示,如果应用程序已经在前台,则调用FirebaseMessagingService.onMessageReceived()

  2. 数据消息:
    有效载荷{"data" : { "key1" : "value1"}}
    即使应用程序关闭或在后台运行,这些消息始终会调用FirebaseMessagingService.onMessageReceived()

click_action是通知有效载荷的一个参数,因此适用于显示消息。

指示与用户单击通知相关联的操作。
如果设置了它,则在用户单击通知时启动具有匹配意图过滤器的活动。

https://firebase.google.com/docs/cloud-messaging/http-server-ref#notification-payload-support


9
还有一件事:Firebase Web控制台仅能发送显示消息。若要发送数据消息,您需要使用服务器端API。 - Diego Giorgini
4
是的。要发送数据消息,你仍然需要实现一个单独的应用服务器,因为Firebase Web控制台只能发送显示消息。如果你希望控制台支持数据消息,请发送一个功能请求:https://firebase.google.com/support/contact/bugs-features/ - Diego Giorgini
4
为进行测试,您可以使用Google Advanced REST Client工具,并将您的JSON消息发送到https://fcm.googleapis.com/fcm/send。 这里有一个示例:http://i.imgur.com/MIOuj2U.png - fralbo
9
我不明白为什么这个答案被接受了。这个答案是为了指定当用户点击通知时应启动哪个活动,而问题是“如何在没有任何用户交互的情况下自动启动特定的活动?” - ENSATE
1
如果应用程序在后台运行并且通知中有数据有效负载,则不会调用FirebaseMessagingService.onMessageReceived(),经过尝试和测试! - Divyanshu Negi
显示剩余6条评论

19

看起来此指南部分是解决后台应用难题的关键:

接收消息
使用扩展FirebaseMessagingServiceservice。您的服务应重写onMessageReceived回调,该回调提供大多数消息类型,但以下情况除外:

当您的应用处于后台时传递的通知。
在这种情况下,通知将传递到设备的系统托盘。用户点击通知时,默认会打开应用启动器。

同时具有通知和数据有效载荷的消息。
在这种情况下,通知将传递到设备的系统托盘,并且数据有效载荷将在您的启动器Activity的意图的extras中传递。

本质上,当应用程序处于后台时,它并没有真正响应或运行。因此,该消息会被传递到系统托盘中。然而,在下面,解决方案得到了解释。

如果您想在后台打开应用程序并执行特定操作,可以将click_action设置在通知有效载荷中,并将其映射到您要启动的Activity的意图过滤器上。例如,将click_action设置为OPEN_ACTIVITY_1以触发像以下这样的一个意图过滤器:

<intent-filter>
  <action android:name="OPEN_ACTIVITY_1" />
  <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

1
我需要类似于自定义消息接收器的东西,可以在其中执行启动应用程序的代码,但我不确定是否已经可以使用 FCM 实现。 - stevyhacker
3
刚才我尝试了GCM,它对我的使用情况没有问题,可惜FCM不支持这个功能。 - stevyhacker
1
感谢您的好解决方案。使用您的解决方案启动了我的目标Activity,但在该Activity中没有获取到额外数据。请问您有什么解决方法吗? - Md. Sajedul Karim
2
这不是回答问题的方法,我们需要在没有用户交互的情况下自动启动活动,比如点击通知。 - ENSATE
1
我期待着你们如何在用户不点击系统托盘通知的情况下自动启动应用程序的答案。 - Zahirul Haque
显示剩余2条评论

8
我在这里总结步骤,希望能对您有所帮助。 步骤1 请参考FCM用户指南。通过从Firebase控制台推送消息确保一切正常运行。 步骤2 将您的自定义FirebaseMessagingService类更改如下:
public class MyFirebaseMessagingService extends FirebaseMessagingService {

private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    Log.d(TAG, "From: " + remoteMessage.getFrom());
    startActivity(new Intent(this, SplashActivity.class));
}
}

现在再次使用Firebase控制台推送消息,您会发现只有当您的应用程序在前台时才会触发onMessageReceived。因为Firebase控制台只能发送通知消息。为了发送数据消息,我们需要进行第三步。

第三步

安装Google高级REST客户端

输入以下参数:

url: https://fcm.googleapis.com/fcm/send
method: POST 
Raw header: 
Content-Type: application/json
Authorization:key=YOUR_SERVER_KEY
Raw payload:
{
   "to" : "YOUR_DEVICE_FCM_TOKEN",
   "data" : {
     "Nick" : "Mario",
     "body" : "great match!",
     "Room" : "PortugalVSDenmark"
   },
 } 

YOUR_SERVER_KEY可以在Firebase控制台的设置面板中找到,进入Cloud Messaging选项卡。

YOUR_DEVICE_FCM_TOKEN是在onTokenRefresh()方法中使用FirebaseInstanceId.getInstance().getToken()获取的。

注意:

未经用户交互即启动UI界面会导致不良的用户体验,您可能需要将启动活动更换为后台服务或类似操作。我只是出于测试目的使用活动,因此它比服务更加直观。感谢@2ndgab介绍了Google高级REST客户端工具。


无法工作。当应用程序在后台时,无法接收任何消息。 - fozua
假设您已经完成第二步,但在第三步失败时发送帖子时收到的响应不是200,请检查您使用的参数。 - thanhbinh84

2
[Android] 如果您正在使用Firebase通知(而不是Firebase云消息传递),则您只需在build.gradle中包含Firebase消息传递,并将您的应用程序连接到Firebase控制台上的项目即可。
如果您的应用程序处于后台,则从控制台发送的任何消息都会给您一个系统通知,如果触摸它,则会激活您的应用程序。
请参见此处:https://youtu.be/KpTSpVh9SfY?t=10m22s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接