GCM(谷歌云消息)无法覆盖所有注册用户?

Posted

技术标签:

【中文标题】GCM(谷歌云消息)无法覆盖所有注册用户?【英文标题】:GCM (Google Cloud Messaging) cannot reach to all registered users? 【发布时间】:2016-11-16 21:30:20 【问题描述】:

我已将 GCM 集成到我的 android 应用中,我的应用已经使用 GCM 运行了 3 个月。

我已按照 Google 的说明进行操作,并且在我的设备(Nexus HTC 9 以及我测试的其他一些设备上)上一切正常。

一般来说,我发送一条数据消息(没有“通知”键),通过 onMessageReceived 方法接收它,在设备获取数据后向我的服务器发送 ping 并运行处理传入数据的代码(显示例如通知)。

当应用程序处于前台、后台或什至完全关闭(重启设备后)时,设备会获取数据。

但是...

每 1-2 周,我向所有用户发送一条数据消息,但我注意到在仍然存在的注册令牌中,以及我从中获得“成功”和“消息 ID”的那些GCM 的回应,最终我只覆盖了大约 50% 的用户(在某些国家甚至更少)。 例如,如果这是响应:

 "multicast_id": 108,
  "success": 5000,
  "failure": 300,
  "canonical_ids": 0,
  "results": [
     "message_id": "1:08" ,
     "message_id": "1:09" 
...
....
....
...
  ]

“成功”表示 5000,但 onMessageReceived 方法仅在 2500 个用户上运行...

我还查看了 FCM 诊断以检查消息 ID 状态,并且似乎设备正在获取消息。

我做的另一个测试,只是为了看看我的代码是好的——一旦用户使用 GCM 提供给我的注册令牌成功注册到我的服务器,我立即向他推送一个“测试/虚拟”数据,只是为了看看用户得到它并且我的代码正在运行并将 ping 发送到我的服务器 - 这个“循环”几乎适用于 100% 的用户......

那么为什么 1-2 周后我无法接触到这些用户并且从大约 100% 下降到 50%...? (我说的只是那些没有卸载我的应用的人)

这是我在GcmListenerService的实现中使用的:

public class GcmMessageHandler extends GcmListenerService 

    @Override
    public void onMessageReceived(String from, Bundle data) 
        ...
        ...
        Context context = getBaseContext();
        sendPingtoMyServer(context)
    

这是清单:

<service
    android:name="[MY_PACKAGE].GcmMessageHandler"
    android:exported="false" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>

<receiver
    android:name="com.google.android.gms.gcm.GcmReceiver"
    android:exported="true"
    android:permission="com.google.android.c2dm.permission.SEND" >
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <category android:name="[MY_PACKAGE]" />
    </intent-filter>
</receiver>

任何帮助将不胜感激。

谢谢

【问题讨论】:

您是否尝试过使用主题消息,看看情况是否也一样? (虽然如果不实现类似delivery receipt的功能,您将无法追踪通过主题发送的消息) 没有测试它,但正如你所说,将无法跟踪它:) 可能会有同样的问题。对我来说奇怪的是,如果我将没有 ping 的消息 id 带回我的服务器,并通过 FCM 诊断工具检查它们,该工具会显示 id 已成功传递到设备。 您找到解决此问题的方法了吗? 【参考方案1】:

根据我的经验,我使用 node-gmc 发送消息,这无关紧要,因为这些是 api 调用。

就我而言,我发送以下参数

var message = new gcm.Message(
   priority: 'high',
   contentAvailable: true,
   content_available: true,
   notification: 
       sound: true,
       title: "StockAlert Notification",
       icon: "ic_launcher",
       body: notification,
   
 ) 

无论如何,我确实遇到了同样的问题,使用参数有所帮助。 出于某种原因,contentAvailable: true 在某些手机上有效,但我不得不为其他手机添加 content_available: true

我也在研究这个问题

【讨论】:

据我了解,contentAvailable 仅适用于 ios 设备,目前我仅针对 Android 设备。另外,我发送的是“数据”消息而不是“通知”消息(发送没有“通知”键,我在 onMessageReceived 中的代码获取数据并显示通知)

以上是关于GCM(谷歌云消息)无法覆盖所有注册用户?的主要内容,如果未能解决你的问题,请参考以下文章

用户之间的 Android 谷歌云消息传递

GCM 是如何工作的? (适用于 Android 的谷歌云消息传递)

谷歌云消息错误服务不可用[重复]

GCM 问题(谷歌云消息)

谷歌云消息安全

关于 GCM 中的规范 ID(谷歌云消息传递)