我查看了所有“未注册”错误的帖子,但无法解决问题。我也联系了Firebase支持,不幸的是他们只给我提供了官方文档的网址。
我们的应用程序已经在商店中运行了一段时间,并且在应用程序处于后台时成功使用GCM进行通知。由于GCM的弃用,我们目前正在尝试迁移到FCM。
简而言之:我们按照官方迁移步骤进行了official migration,更改了Android客户端中的代码,更新了Firebase控制台,下载/添加了
现在我们面临的问题如下: 应用程序使用
我们在这些设备上尝试了我们的运气:
我知道
Android客户端使用以下依赖项:
应用服务器
在服务器端,我们正在使用以下库。根据文档和这个帖子,我们应该能够仅通过适应的端点URL(https://fcm.googleapis.com/fcm/send)使用相同的库,而无需进行任何进一步的更改:
通知的构建如下:
并使用此调用发送:
Firebase控制台
我上传了应用程序的调试和发布SHA1。我还尝试从Firebase控制台发送消息(Grow> Cloud messaging> Notifications),但Android上仍然没有收到消息。
有趣的是,我们的iOS应用程序版本没有任何问题,它也使用FCM。来自应用程序服务器和Firebase控制台的消息都成功到达。但是,iOS应用程序从未使用过GCM。
有什么线索吗?我们忘记了什么?感谢您阅读到这里!
我们的应用程序已经在商店中运行了一段时间,并且在应用程序处于后台时成功使用GCM进行通知。由于GCM的弃用,我们目前正在尝试迁移到FCM。
简而言之:我们按照官方迁移步骤进行了official migration,更改了Android客户端中的代码,更新了Firebase控制台,下载/添加了
google-services.json
并调整了应用服务器上的终端点URL。现在我们面临的问题如下: 应用程序使用
FirebaseInstanceId
单例请求令牌,并成功接收到令牌。然后,我们将此令牌转发到我们的应用程序服务器,该服务器将其保存在数据库中。然后,服务器想使用Sender.sender(...)
方法向Android设备发送消息,但收到臭名昭著的“NotRegistered”错误。所有这些都发生在大约10秒内。我们在这些设备上尝试了我们的运气:
- 模拟器设备 Nexus 5X API 27 x86
- Nexus 5X API 23
- Pixel 2 API 28
查看list中返回NotRegistered错误的原因,我可以评论如下:
- 客户端应用程序取消注册FCM ->由于我们控制手机,我可以排除此点
- 卸载应用程序 ->这里也是一样的
- 注册令牌过期 ->可能性很大,但在10秒内?
- "如果客户端应用程序已更新,但新版本未配置为接收消息" ->这到底是什么意思?由于该应用程序之前能够接收消息,我想它已经配置好接收消息了。
Android客户端
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.acme.app">
<!-- permissions omitted for brevity -->
<application
android:name=".App"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/AppTheme"
tools:node="replace">
<!-- Register AnalyticsReceiver and AnalyticsService to support background dispatching for Google Analytics on non-Google Play devices. -->
<receiver
android:name="com.google.android.gms.analytics.AnalyticsReceiver"
android:enabled="true">
<intent-filter>
<action android:name="com.google.android.gms.analytics.ANALYTICS_DISPATCH" />
</intent-filter>
</receiver>
<service
android:name="com.google.android.gms.analytics.AnalyticsService"
android:enabled="true"
android:exported="false" />
<service
android:name=".gcm.MyGcmListenerService"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".gcm.MyInstanceIDListenerService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<!-- this is need for the firebase messaging service. It should be included automatically, but somehow gets deleted by the AndroidManifest file merging. So we manually have to add it -->
<service android:name="com.google.firebase.components.ComponentDiscoveryService">
<meta-data
android:name="com.google.firebase.components:com.google.firebase.iid.Registrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
<!-- omitted for brevity -->
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/notification_icon" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/base_color" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id" />
</application>
</manifest>
活动中的代码(简化版)
String token = FirebaseInstanceId.getInstance().getToken();
sendTokenToServer(token);
FirebaseMessaging.getInstance().subscribeToTopic("news");
Services
public class MyGcmListenerService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage message) {
...// never called
}
}
我知道
FirebaseInstanceIdService
已被弃用,但我也尝试了新版本,但仍然无法工作。public class MyInstanceIDListenerService extends FirebaseInstanceIdService {
@Override
public void onTokenRefresh() {
// never called...
String token = FirebaseInstanceId.getInstance().getToken();
sendTokenToServer(token);
}
}
Android客户端使用以下依赖项:
implementation "com.google.firebase:firebase-core:16.0.7"
implementation "com.google.firebase:firebase-messaging:17.4.0"
应用服务器
在服务器端,我们正在使用以下库。根据文档和这个帖子,我们应该能够仅通过适应的端点URL(https://fcm.googleapis.com/fcm/send)使用相同的库,而无需进行任何进一步的更改:
com.google.gcm:gcm-server:1.0.0
通知的构建如下:
private Message buildMessage(String title, String body, Map<String, String> attributes) {
final Notification.Builder notificationBuilder = new Notification.Builder(null)
.body(body)
.title(StringUtils.trimToNull(title));
final Message.Builder messageBuilder = new Message.Builder()
.addData(KEY_BODY, body)
.notification(notificationBuilder.build());
if (!Strings.isNullOrEmpty(title)) {
messageBuilder.addData(KEY_TITLE, title);
}
for (Map.Entry<String, String> attr : attributes.entrySet()) {
messageBuilder.addData(attr.getKey(), attr.getValue());
}
return messageBuilder.build();
}
并使用此调用发送:
Result result = sender.send(message, deviceToken, retryCount);
if (result.getMessageId() == null) {
if (ERROR_CODE_NOT_REGISTERED.equals(result.getErrorCodeName())) { // <-- returns NotRegistered
// omitted
}
}
Firebase控制台
我上传了应用程序的调试和发布SHA1。我还尝试从Firebase控制台发送消息(Grow> Cloud messaging> Notifications),但Android上仍然没有收到消息。
有趣的是,我们的iOS应用程序版本没有任何问题,它也使用FCM。来自应用程序服务器和Firebase控制台的消息都成功到达。但是,iOS应用程序从未使用过GCM。
有什么线索吗?我们忘记了什么?感谢您阅读到这里!