在收到 firebase 通知时打开应用程序 (FCM)

Open app on firebase notification received (FCM)

我想在收到通知时自动打开应用程序,这可以通过 Firebase 和新的 FCM 通知实现吗?

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

我尝试了快速启动消息传递 firebase 示例,并且有一个 onMessageReceived() 方法,但它仅在应用程序位于前台时才有效。应用程序在后台时是否也会执行某些操作? GCM 可以通过直接从收到通知时调用的广播接收器启动 activity intent 来做我想做的事情。

看来this section of the guide是后台应用之谜的关键:

To receive messages
Use a service that extends FirebaseMessagingService. Your service should override the onMessageReceived callback, which is provided for most message types, with the following exceptions:

Notifications delivered when your app is in the background.
In this case, the notification is delivered to the device’s system tray. A user tap on a notification opens the app launcher by default.

Messages with both notification and data payload.
In this case, the notification is delivered to the device’s system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.

本质上,当应用程序处于后台时,它并不是真正的响应或 运行 此时。因此,消息被传送到系统托盘。然而,就在下面,解释了解决方案。

If you want to open your app and perform a specific action [while backgrounded], set click_action in the notification payload and map it to an intent filter in the Activity you want to launch. For example, set click_action to OPEN_ACTIVITY_1 to trigger an intent filter like the following:

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

快速回答:

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

然后你可以在.onMessageReceived()方法中添加你的逻辑来启动首选activity.

警告: 在没有任何用户交互的情况下启动 UI 对于大多数应用程序来说是非常非常糟糕的做法!请在此处阅读 MarkG 的回答: How to start an Activity from a Service?

[...] Interrupting what the user is currently doing is considered bad design form, especially from something that is supposed to be operating in the background.
Therefore, you should consider using a Notification [...] to launch the desired Activity when the user decides it is time to investigate. [...]

完整解释:

FCM 的工作原理与 GCM 类似,可以接收两种类型的消息:

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

  2. 数据消息:
    有效负载{"data" : { "key1" : "value1"}}
    这些消息 总是调用 FirebaseMessagingService.onMessageReceived(),
    即使应用程序已关闭或处于后台。

click_action是notification payload的一个参数,因此适用于display-messages。

Indicates the action associated with a user click on the notification.
If this is set an activity with a matching intent filter is launched when user clicks the notification.

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

[Android] 如果您使用的是 Firebase 通知(而不是 Firebase 云消息传递),您所要做的就是在您的 build.gradle 中包含 Firebase 消息传递,然后 link 您的应用程序到 Firebase 控制台上的项目。

如果您的应用程序在后台,从控制台发送的任何消息都会给您一个系统通知,如果触摸该通知,将激活您的应用程序。

看这里:https://youtu.be/KpTSpVh9SfY?t=10m22s

我把步骤总结到这里,希望对你有帮助

第 1 步

关注 FCM user guide. Make sure everything work properly by pushing a message from Firebase console

第 2 步

更改您的自定义 FirebaseMessagingService class 如下:

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 控制台只能发送 Notification message。为了发送 Data message,我们需要第 3 步。

第 3 步

安装Google Advanced REST client

在参数下方输入:

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 控制台>“设置”窗格>“云消息传递”选项卡中可用

YOUR_DEVICE_FCM_TOKEN 在 onTokenRefresh()

FirebaseInstanceId.getInstance().getToken()

注意

在没有用户交互的情况下启动 UI 是糟糕的用户体验,您可能需要将启动 activity 替换为启动服务或在后台运行。我只是为了测试目的使用 activity,所以它比服务更直观。 感谢 @2ndgab 介绍 Google 高级 REST 客户端工具。