FirebaseMessagingService 11.6.0 HandleIntent

Posted

技术标签:

【中文标题】FirebaseMessagingService 11.6.0 HandleIntent【英文标题】: 【发布时间】:2018-04-28 17:19:58 【问题描述】:

FirebaseMessagingServiceonMessageReceived() 方法,我们应该 override 处理 notifications,但这仅在应用程序位于 Foreground 时有效。

即使应用程序在后台处理notifications,我也曾经覆盖handleIntent,只调用onMessageReceived()

FirebaseMessagingService 11.6.0 中,方法handleIntent 成为最终方法,话虽如此,我不能像以前那样覆盖它。

当我的应用在 11.6.0 中处于后台时,我应该如何处理通知?

public class NotificationsListenerService extends FirebaseMessagingService 
    private static final String TAG = "NotificationsListenerService";

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) 

        String notifyData = remoteMessage.getData().get("notifData");

        if(notifyData.contains("|"))
            String[] itens = notifyData.split("\\|");
            notifyData = itens[0];
        


        String notifyType = remoteMessage.getData().get("notifType");
        String title = remoteMessage.getData().get("title");
        String message = remoteMessage.getData().get("body");

        if(!isAppInForeground(App.getContext()))
            sendNotification(title, message, notifyData, notifyType);
        
    

    @Override
    public final void handleIntent(Intent intent) 
        ...
        this.onMessageReceived(builder.build());
        ...
    

    private void sendNotification(String messageTitle, String messageBody, String notifyData, String notifyType) 
        ...
    


    //Detect if app is in foreground
    private boolean isAppInForeground(Context context) 
        ...
    

【问题讨论】:

【参考方案1】:

不适合任何人覆盖handleIntent()。这就是为什么它被定为最终版本。此外,您会注意到 javadocs 中完全没有它 - 这是故意的。

如果您想在任何情况下(前台和后台)处理消息,请使用onMessageReceived()。该方法的javadoc 表示:

收到消息时调用。

在收到通知消息时调用,而 应用程序在前台。可以检索通知参数 使用 getNotification()。

这应该适用于数据消息,但不适用于从控制台发送的通知消息。通知消息具有不同的传递行为。请参阅有关 message types 和 how to handle them 的文档。

【讨论】:

我读过那些文章,但是当我的应用程序在后台时,它只会收到通知,但是当用户点击它时,通知就会被关闭。我已经开发了在通知中单击的逻辑,以将用户引导至特定活动。当我用来覆盖handleIntent时,它工作得很好。 这太可怕了。我们现在无法升级,因为我们的后端服务器向 iosandroid 发送相同的通知,所以我们所有的 android 推送消息都有通知设置。有了这个变化,如果后端系统开始根据接收消息的设备区分它们通过 FCM 发送的消息,我们现在就不可能按照需要呈现通知。 @JakeHall 我处于完全相同的情况,不能使用仅数据消息,因为当应用程序被杀死时 iOS 不会收到。 @annihil 我们最终不得不创建自己的 BroadcastReceiver 和 JobIntentService 实现来接收 FCM 消息并显式提取意图过滤器,这些过滤器将消息发送到使用其 SDK 提供的 FCM 类 @JakeHall 你有那个 Receiver 和 JobIntentService 开源吗?【参考方案2】:

我要在 FirebaseMessagingService 11.8.0 文档中补充一点,https://firebase.google.com/docs/cloud-messaging/android/receive 中指出,如果通知具有数据有效负载,它将在应用程序处于前台时调用 onMessageRecieved(),并且如果应用程序处于通知和数据有效负载的背景是在您的启动器 Activity 的意图的附加内容中传递的。

因此,这意味着您需要决定如何在两个地方处理通知,具体取决于用户是在积极使用应用还是在后台。

如您所见,如果您在应用程序处于前台时收到通知,则会调用 onMessageReceived() 并在那里处理通知。

当应用程序从后台启动时,您有 2 个选项:

1:默认情况下,通知会发送到您的系统托盘,当点击它时,它会打开您的主要活动,将数据(onMessageReceived() 中的 remoteMessage.getData())传递给您的活动意图额外。您可以像这样处理主要活动中的额外内容并决定如何处理它们,例如检查键值并启动相关意图。

    // [START handle_data_extras]
    if (getIntent().getExtras() != null) 
        for (String key : getIntent().getExtras().keySet()) 
            Object value = getIntent().getExtras().get(key);
            Log.d(TAG, "Key: " + key + " Value: " + value);
        
    
    如果您在应用清单中添加意图过滤器并在通知中添加指定的“click_action”值,您可以决定在点击时打开什么意图,然后在指定的活动中处理意图额外内容。见https://***.com/a/39665485/3746204

我还建议检查 firebase 消息传递示例应用程序以获取想法:https://github.com/firebase/quickstart-android/tree/master/messaging

【讨论】:

【参考方案3】:

我在更新 firebase 库版本后遇到了同样的问题。

我认为最简单的方法是再次降级 firebase 库(我使用 11.4.2)并且handleIntent() 仍然有效!

【讨论】:

这绝对不是解决问题的办法。 是的,从 2 天开始搜索,我认为这将是解决问题但有效的解决方案 @MMoersalin 这更像是一种 hack,如果 11.4.2 中存在错误并且 OP 面临该错误并且除了升级到最新版本之外别无他法,会发生什么?

以上是关于FirebaseMessagingService 11.6.0 HandleIntent的主要内容,如果未能解决你的问题,请参考以下文章

FirebaseMessagingService 11.6.0 HandleIntent

安装应用程序时永远不会调用 FirebaseMessagingService

如何像 whatsapp 在 FirebaseMessagingService 中合并推送通知

如何从 FirebaseMessagingService 的 onNewToken() 访问我的布局?

自定义 Flutter Android FirebaseMessagingService

从 FirebaseMessagingService 类调用活动类方法