Firebase中应用程序在后台时如何处理通知

新手上路,请多包涵

这是我的清单:

 <service android:name=".fcm.PshycoFirebaseMessagingServices">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<service android:name=".fcm.PshycoFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>

当应用程序在后台并收到通知时,默认通知会出现并且不会运行我的代码 onMessageReceived

这是我的 onMessageReceived 代码。如果我的应用程序在前台运行,而不是在后台运行,则会调用此方法。当应用程序也在后台时,如何运行此代码?

 // [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    // TODO(developer): Handle FCM messages here.
    // If the application is in the foreground handle both data and notification messages here.
    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
    data = remoteMessage.getData();
    String title = remoteMessage.getNotification().getTitle();
    String message = remoteMessage.getNotification().getBody();
    String imageUrl = (String) data.get("image");
    String action = (String) data.get("action");
    Log.i(TAG, "onMessageReceived: title : "+title);
    Log.i(TAG, "onMessageReceived: message : "+message);
    Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
    Log.i(TAG, "onMessageReceived: action : "+action);

    if (imageUrl == null) {
        sendNotification(title,message,action);
    } else {
        new BigPictureNotification(this,title,message,imageUrl,action);
    }
}
// [END receive_message]

原文由 Parth Patel 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 789
2 个回答

1. 为什么会这样?

FCM(Firebase Cloud Messaging)中有两种类型的消息:

  1. 显示消息:这些消息仅在您的应用程序处于 前台 时触发 onMessageReceived() 回调
  2. 数据消息:这些消息触发 onMessageReceived() 回调 ,即使 您的应用程序处于 前台/后台/ 已终止

注意: Firebase 团队尚未开发 UI 以将 data-messages 发送到您的设备。您应该使用您的服务器发送此类型!

2. 怎么做?

为此,您必须向以下 URL 执行 POST 请求:

POST https://fcm.googleapis.com/fcm/send

标头

  • 键: Content-Type值: application/json
  • 键: Authorization值: key=<your-server-key>

正文使用主题

{
    "to": "/topics/my_topic",
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     }
}

或者,如果您想将其发送到特定设备

{
    "data": {
        "my_custom_key": "my_custom_value",
        "my_custom_key2": true
     },
    "registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}

注意: 确保您 没有添加 JSON 密钥 notification

注意: 要获取您的服务器密钥,您可以在 Firebase 控制台中找到它: Your project -> settings -> Project settings -> Cloud messaging -> Server Key

3. 推送通知消息如何处理?

这是您处理收到的消息的方式:

 @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
     Map<String, String> data = remoteMessage.getData();
     String myCustomKey = data.get("my_custom_key");

     // Manage data
}

原文由 Antonio 发布,翻译遵循 CC BY-SA 4.0 许可协议

为了能够从应用程序处于后台时发送的 firebase 通知中检索数据,您需要在通知数据集中添加 click_action 条目。

在 firebase 控制台中设置通知的其他选项,如下所示:( _您必须在此处包含要在应用程序中检索的任何额外数据_): 将 click_action 添加到 Firebase 通知

并在要启动的活动下的清单文件中包含意图过滤器

    <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyApp.SplashScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            <intent-filter>
                <action android:name="FIREBASE_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
    </activity>

然后在您的活动 onNewIntent 中获取捆绑数据:

     @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Bundle data = intent.getExtras();
        if (data != null) {
            for (String key : data.keySet()) {
                Object value = data.get(key);
                // do what you want with the data entries
                Log.d(FIREBASE_TAG, "Key: " + key + " Value: " + value);
                Toast.makeText(this, "Key: "+key+"....  Value: "+value, Toast.LENGTH_LONG).show;
            }
        }
    }

当您的应用程序处于前台时,您可以像这样设置 onMessageReceived

 @Override
    public void onMessageReceived(@NonNull RemoteMessage message) {
        Log.d(FIREBASE_TAG, "Message From: " + message.getFrom());

        if (message.getNotification() != null) {
            Intent intent = new Intent(this, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            Map<String, String> data = message.getData();
            if(data != null && !data.isEmpty()){
                for(Map.Entry<String ,String > entry : data.entrySet()) {
                    intent.putExtra(entry.getKey(), entry.getValue());
                }
            }
            //.......
            // implement the rest of the code to show notification
            //
        }
    }

原文由 Akinyemi Jamiu 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题