Firebase推送通知更新数据库。

6
我正在尝试通过新的Firebase推送通知服务向我的用户发送一些数据。 我添加了一些“键值”自定义数据项,使用“消息文本” - “dbupdate”来检测它是否是更新消息还是我想要向用户展示的普通推送通知。 在接收器中,如果存在自定义数据,则运行更新操作。 如果不是这种情况,则显示带有文本消息的普通通知。 只有当我的应用程序打开时才能正常工作。如果应用程序关闭,通知将仍然显示,并且我的if检查甚至不运行, 以下是一些代码:
public class PushMessageService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Map<String,String> data = remoteMessage.getData();
        String link = data.get("link");
        String name = data.get("name");
        if (link!=null) {
            Log.d("link",link);
            Log.d("name",name);
            UpdateHelper.Go(this, link, name);
        }
        else {
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_shop_white_24dp)
                            .setAutoCancel(true)
                    .setContentTitle(remoteMessage.getNotification().getTitle())
                   .setContentText(remoteMessage.getNotification().getBody());
            NotificationManager mNotificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(5, mBuilder.build());
        }
    }
}

示例通知 在这里

为什么会这样?我该怎么做才能在应用程序关闭后运行我的代码?


你的推送消息中有任何“通知”标签吗? - Reaz Murshed
我的通知标签为空。 - Nirel
即使通知标签为空,也要删除它。 - Reaz Murshed
我无法删除通知栏。请看我的截图。 - Nirel
请发布您的通知的JSON主体。 - Reaz Murshed
3个回答

26

根据我的Firebase推送经验:

问题:通过“Firebase控制台”发送推送通知时,仅在应用程序处于前台时才会接收到通知。如果应用程序被杀死或处于后台,则在版本>=棒棒糖中仅显示具有错误通知图标的通知并/或打开应用程序中的默认启动器活动,即使您已在PendingIntent中定义了不同的Activity。

根据Firebase文档,推送消息分为两部分,他们称之为:文档链接在此

  1. 通知
  2. 数据有效载荷

输入图片说明

解决方法:

有两种方法可以发送“推送”消息。

1. Firebase控制台

Console

2. Messaging API- 显示使用高级REST客户机的请求的图像

Curl Request

onMessageReceived(...)方法中接收推送消息。Firebase的onMessageReceived(...)方法不会在应用程序处于后台或已杀死时被调用,仅当通过Firebase控制台发送消息时才会这样。

如果通过API发送消息,则运行良好。无论应用程序处于后台、前台还是已杀死状态,消息都会传递到onMessageReceived(...)方法中。(注意:在>=棒棒糖中可以正常工作-Android 4.4或以下的行为仍然不可预测。)

更新:

您可以像这样从API发送下行消息(Firebase称之为下行消息):https://firebase.google.com/docs/cloud-messaging/downstream

从服务器发送下行消息

为了定位或“定位”下行消息,应用程序服务器将其设置为接收客户端应用程序的注册令牌。您可以使用预定义字段或自定义数据消息发送通知消息;有关有效载荷支持的详细信息,请参见消息负载中的通知和数据。此页面中的示例显示如何在HTTP和XMPP协议中发送数据消息。

HTTP POST请求

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

谢谢您的评论,那么我该如何使用Messaging API呢? 文档中没有提到" Messaging API"。 - Nirel
1
@HishamMuneer。你能否验证一下,通过API你仍然可以向后台应用程序发送数据消息(我的意思是不是几周前构建的apk,而是在所有更新之后重新构建的),因为直到最近这对我起作用。不幸的是,从几周前完全相同的工作项目中,我无法再让它正常工作!?! - fralbo
@2ndGAB 我正在使用以下版本,它完美地工作:compile 'com.google.firebase:firebase-messaging:9.0.1'。然而,我对Firebase未来的发布还不确定。 - Hisham Muneer
我收到了HTTP/1.1 400 Bad Request错误,我的POST请求是fcm.googleapis.com/fcm/send,Content-Type为application/json,Authorization为key=GduFdg......wK8B4Uwk2xxx...。请求体如下:{ "data": { "message": "post message", "version" : "2.0: }, "to" : "fasdsadasdsadasj9N40:APA91bGCX.....t85nX--HGg......N" } 请问出了什么问题? - Sagar Patil
这是关于如何从Firebase发送数据消息的最真实的答案,致敬。 - Tech Nerd

2

"data-messages: payload {"data" : { "key1" : "value1"}}} 这些消息总是会调用FirebaseMessagingService.onMessageReceived(),即使应用程序已关闭或在后台运行。- Diego Giorgini在您提供的第二个链接中提到了这一点,所以这是可能的,为什么它不起作用呢? - Nirel
@Nirel,它之前一直能用。我有一个应用程序,建立并发布于2016年08月07日,完美地在后台接收数据消息。但现在,即使我从完全相同的项目重新构建,也无法使其工作。可能是sdk、studio、java更新,不幸的是我不能确定。 - fralbo
是的,这只在应用程序处于前台时工作。如果在后台运行,则无法工作。 - Norlihazmey Ghazali

1
在Android中,如果您想在应用程序处于前台/后台/终止状态时更新应用程序中的某些内容,则最好的方法是删除通知负载并仅发送数据负载。
{ 
 "to" : "ee8....DYarin",
    "data" : {
         "key" : "value"
    }   
}

在这种情况下,onMessageReceived() 将会被执行。(在一些安卓设备上,比如小米手机,你需要启用自启动才能处理终止状态下的推送)
那么,在这种情况下,你将如何向用户显示通知?你可以将标题和正文作为数据负载中的自定义标签传递,并通过编程生成通知。因此,在安卓系统中,没有通知负载也可以正常运行。

如果您在Android中有通知负载,则存在以下问题:

  • 如果应用程序在前台,则一切正常,通知将显示并且将执行onMessageReceived()
  • 如果应用程序处于后台/终止状态,则通知将显示在设备上,但仅当您单击通知时,onMessageReceived()才能工作。用户倾向于经常清除它们,我们的代码在onMessageReceived()中不会被执行。

此外,要启用通知上的单击功能,通知负载应包含名为click_action的键:

"notification":{
        "title":"Prime",
        "body" : "test",
         "click_action": "my_click_action_name"
}

你需要在你的活动中将该操作注册为 intent_filter

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

每当用户点击通知时,对应活动的onNewIntent()方法被调用,并且数据负载可以在对应的intent.getExtras()中获得。

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