【问题标题】:Data messages from FCM not enabling onMessagereceived when app is killed当应用程序被杀死时,来自 FCM 的数据消息未启用 onMessagereceived
【发布时间】:2017-05-16 09:00:18
【问题描述】:

根据https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages,我可以使用将 100% 收到 onMessageReceived 方法的数据消息并采取相应措施。但就我而言,当应用程序被杀死时,我的任何消息都没有收到。虽然它们有时会在我仅在 Nexus 5 上进行测试时收到。下面是我的数据负载。

05-16 06:46:01.663 13199-29574/jss.test E/MyFirebaseMsgService: Data Payload: {data={"image":null,"title":"My message"}}
05-16 06:46:01.667 13199-29574/jss.test E/Providerfalse: true
05-16 06:46:01.667 13199-29574/jss.test E/MyFirebaseMsgService: Notification JSON {"data":{"image":null,"title":"My message"}}

FCM 清单如下:

 <service
            android:name=".FirebaseMessagingService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

Firebase 消息服务:

  @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        if (remoteMessage.getData().size() > 0) {

            Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());
            try {
                JSONObject json = new JSONObject(remoteMessage.getData().toString());
                sendPushNotification(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: " + e.getMessage());
            }
        }
    }


    //this method will display the notification
    //We are passing the JSONObject that is received from
    //firebase cloud messaging
    private void sendPushNotification(JSONObject json) {
                   //optionally we can display the json into log
        Log.e(TAG, "Notification JSON " + json.toString());
        try {
            //getting the json data
            JSONObject data = json.getJSONObject("data");

            //parsing json data
            String title = data.getString("title");
            String message = data.getString("message");
            String imageUrl = data.getString("image");

//code to call service if message has specific data values.
    }
        catch (Exception e) {
                    e.printStackTrace();    }}

您能否指导我修复的位置以使其完美运行。

【问题讨论】:

  • 你能分享你的 FirebaseMessagingService.java 代码吗?
  • 为 FMS.java 添加了代码
  • 一些可能有用的细节here
  • 您找到解决方案了吗?找不到解决方案,真是令人沮丧。
  • 您好,如果您有解决方案,请提供解决方案。谢谢。

标签: android firebase push-notification firebase-cloud-messaging


【解决方案1】:

根据我在 fcm 实现中的测试,如果我在数据和通知键中都传递数据,那么我能够在 onMessageReceived 方法中仅在应用程序运行时获得通知,否则我无法获得通知,并且如果我正在使用只有用于发送通知的数据键,然后它在两种情况下都有效, 因此,如果您的通知数据中存在通知键,请删除它,并对其进行测试,它可能会起作用。

【讨论】:

  • 它不存在,如果你看数据负载接收,只有数据对象。你确定当你杀死应用程序时,即使你收到通知
  • 是的,如果我不使用通知键,那么它工作得很好
  • 我正在使用 php 发送使用 firebase 的发送方法的通知。我希望我使用正确。任何关于此的指南。
  • 你能分享你如何发送通知吗?可能会提供一些线索。
  • 这就是我使用的方式..$firebase = new Firebase(); //发送推送通知并显示结果 echo $firebase->send($devicetoken, $mPushNotification);
【解决方案2】:

试试下面的方法对你有帮助

private void sendNotification(String text, String senderId, String receiverId) {
        HttpsURLConnection conHttp = null;
        try {

            URL url = new URL("https://fcm.googleapis.com/fcm/send");
            conHttp = (HttpsURLConnection) url.openConnection();
            conHttp.setDoOutput(true);
            conHttp.setDoInput(true);
            conHttp.setRequestMethod("POST");
            conHttp.setRequestProperty("Content-Type", "application/json");
            //Put below you FCM API Key instead
            conHttp.setRequestProperty("Authorization", "key="
                    + “YOUR_FCM_API_KEY”);

            JSONObject root = new JSONObject();
            JSONObject data = new JSONObject();
            data.put(KEY_FCM_TEXT, text);
            data.put(KEY_FCM_SENDER_ID, sender);
            root.put("data", data);
            root.put("to", "/topics/user_" + receiverId);

            byte[] outputBytes = root.toString().getBytes("UTF-8");
            OutputStream os = conHttp.getOutputStream();
            os.write(outputBytes);
            os.flush();
            os.close();
            conHttp.getInputStream(); //do not remove this line. request will not work without it gg

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (conHttp != null) conHttp.disconnect();
        }
    }

【讨论】:

  • 什么是发送者ID和接收者ID?
  • 应用了您的代码,这里是数据值 {"KEY_FCM_TEXT":"test","KEY_FCM_SENDER_ID":"4849877"}{"data":{"KEY_FCM_TEXT":"test","KEY_FCM_SENDER_ID ":"4849877"},"to":"\/topics\/user_ekBwmk__gzs:APA91bFU6oTveaF0fYNyswVzZ5C8ycghM6A-dmcbMFvojxOHTF_GUoRLhIRD1a89aSgx0QQcADw90NRBxviKlGHK1WLpOJfsxRlgmNKgNT2mlA"} 但没有收到关于目标的通知。此处有任何错误。
  • 等待您的支持,
  • 我仍然无法帮助你,因为我已经描述过你的原因之一,可能是你需要检查你的设备安全性。
  • 我发现它适用于 moto、nexus、华硕和其他一些设备,如三星,但不适用于 oppo、vivo 等。我知道这是这些设备和操作系统设置的安全问题。但是许多应用程序都可以工作
【解决方案3】:

在您的服务清单中再定义一件事:

android:stopWithTask="false"

它应该可以工作,否则在应用程序被杀死时没有方法从 onMessageReceived 获取消息。

【讨论】:

  • 另一种解决方案是,创建在消息事件中广播的广播接收器。
【解决方案4】:

尝试使用 getBody() 代替 getData():

    @Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    if (remoteMessage.getBody().toString.length() > 0) {

        Log.e(TAG, "Data Payload: " + remoteMessage.getBody().toString());
        try {
            JSONObject json = new JSONObject(remoteMessage.getBody().toString());
            sendPushNotification(json);
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
    }
}


//this method will display the notification
//We are passing the JSONObject that is received from
//firebase cloud messaging
private void sendPushNotification(JSONObject json) {
               //optionally we can display the json into log
    Log.e(TAG, "Notification JSON " + json.toString());
    try {
        //getting the json data
        JSONObject data = json.getJSONObject("data");

        //parsing json data
        String title = data.getString("title");
        String message = data.getString("message");
        String imageUrl = data.getString("image");

}
    catch (Exception e) {
                e.printStackTrace();    }}

【讨论】:

  • 我可以使用你的建议,但第一个服务应该在应用程序被杀死时启动,但它没有发生。我添加了代码 onCreate 来检查它是否在通知发送时启动,但它没有。在这种情况下,仅放置 .getbody 将如何工作。
【解决方案5】:
public class MyService extends Service {
    public MyService() {
    }
    public int onStartCommand(Intent intent, int flags, int startId) {
       // Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();

        // For each start request, send a message to start a job and deliver the
        // start ID so we know which request we're stopping when we finish the job
       startService(new Intent(getApplicationContext(),          FirebaseMessagingService.class));

        // If we get killed, after returning from here, restart
        return START_STICKY;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

【讨论】:

  • 创建一个像上面这样的服务并返回 STICKY 以在您的应用程序被终止时启用该服务,然后添加“ startService(new Intent(getApplicationContext(), FirebaseMessagingService.class));”这将启动您的 FirebaseMessagingService 。不要忘记从数据中检索您的 Firebase 消息。
猜你喜欢
  • 1970-01-01
  • 2020-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 2018-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多