【问题标题】:FCM Data messages are not working properlyFCM 数据消息无法正常工作
【发布时间】:2018-07-21 22:41:18
【问题描述】:

我正在使用数据消息,即使应用程序被终止或在后台或前台,我们也可以发送消息。我正在使用 FCM 。 但就我而言,有时我的应用程序不会收到这些消息。我正在从应用程序到应用程序发送消息。有时,即使应用程序被杀死或从后台删除,应用程序也会收到消息,但有时它不会。 当我打开应用程序时,突然出现消息。收到特定消息时,我正在打开活动。我知道即使应用程序被杀死或在后台或在前台,数据消息也用于发送消息,但我遇到了这样的问题。请帮忙 !.. 我希望它是绝对的。 我只希望我的应用程序始终连接到 FirebaseMessagingServices ,即使它被杀死。我不了解服务,有人说我需要创建前台服务。如何创建它并实现到 FirebaseMessagingServices .?

MYFirebaseMessaging.java

package com.example.praful.ubercoustomer.Service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
import android.widget.Toast;

import com.example.praful.ubercoustomer.AcceptedWindow;
import com.example.praful.ubercoustomer.Common.Common;
import com.example.praful.ubercoustomer.CompanycancelledtheBooking;
import com.example.praful.ubercoustomer.DeclinedWindow;
import com.example.praful.ubercoustomer.Helper.NotificationHelper;
import com.example.praful.ubercoustomer.Onthewayandimreached;
import com.example.praful.ubercoustomer.R;
import com.example.praful.ubercoustomer.RateActivity;
import com.example.praful.ubercoustomer.VerifyingCompletedBooking;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class MyFirebaseMessaging extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(final RemoteMessage remoteMessage) {


        if (remoteMessage.getData() != null) {
            Map<String, String> data = remoteMessage.getData();
            String title = data.get("title");
            final String companyName = data.get("CompanyName");
            final String BookingIdC = data.get("BookingIdC");
            final String BookingIdT = data.get("BookingIdT");
            final String companyPhone = data.get("CompanyPhone");
            final String companyRates = data.get("CompanyRates");
            final String companyId = data.get("CompanyId");
            final String Date = data.get("Date");
            final String companyIdC = data.get("companyIdC");
            final String Time = data.get("Time");
            final String Id = data.get("Id");
            final String Address = data.get("Address");
            final String Bookingid = data.get("Bookingid");
            final String TimeCB = data.get("TimeCB");
            final String DateCB = data.get("DateCB");
            final String EventType = data.get("EventType");
            final String messageCB = data.get("messageCB");
            final String AddressCB = data.get("AddressCB");
            final String companythatcancelledthebooking = data.get("CompanyNamethatcancelledthebooking");

            final String message = data.get("message");
            //  remoteMessage.getNotification().getTitle() = title and  remoteMessage.getNotification().getBody() = message
            if (title != null && title.equals("Cancel")) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(MyFirebaseMessaging.this, DeclinedWindow.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);

                        Common.isCompanyFound = false;
                        Common.companyId = "";
                        Toast.makeText(MyFirebaseMessaging.this, "" + message, Toast.LENGTH_SHORT).show();
                    }
                });
            } else if (title != null && title.equals("cancelAdvanceBooking")) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(getBaseContext(), CompanycancelledtheBooking.class);
                        intent.putExtra("DateCB", DateCB);
                        intent.putExtra("TimeCB", TimeCB);
                        intent.putExtra("messageCB", messageCB);
                        intent.putExtra("AddressCB", AddressCB);
                        intent.putExtra("EventType", EventType);
                        intent.putExtra("Id", Id);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);

                        Common.isCompanyFound = false;
                        Common.companyId = "";
                        Toast.makeText(MyFirebaseMessaging.this, "" + messageCB, Toast.LENGTH_SHORT).show();
                    }
                });

            } else if (title != null && title.equals("Accept")) {


                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(MyFirebaseMessaging.this, AcceptedWindow.class);
                        intent.putExtra("Date", Date);
                        intent.putExtra("Time", Time);
                        intent.putExtra("Address", Address);
                        intent.putExtra("companyName", companyName);
                        intent.putExtra("companyPhone", companyPhone);
                        intent.putExtra("companyRates", companyRates);
                        intent.putExtra("companyId", companyId);
                        intent.putExtra("Bookingid", Bookingid);
                        intent.putExtra("EventType", EventType);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);
                        Common.isCompanyFound = false;
                        Common.companyId = "";


                        Toast.makeText(MyFirebaseMessaging.this, "" + message, Toast.LENGTH_SHORT).show();
                    }
                });

            } else if (title != null && title.equals("Arrived")) {
                Handler handler = new Handler(Looper.getMainLooper());

                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                            showArrivedNotifAPI26(message);
                        else
                            showArrivedNotif(message);

                    }
                });
            } else if (title != null && title.equals("Completed")) {

                openRateactivity(message);
            } else if (title != null && title.equals("completedAdvancebooking")) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(MyFirebaseMessaging.this, VerifyingCompletedBooking.class);
                        intent.putExtra("BookingIdC", BookingIdC);
                        intent.putExtra("message", message);
                        intent.putExtra("companyid", companyIdC);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);

                    }
                });
            } else if (title != null && title.equals("Ontheway")) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(MyFirebaseMessaging.this, Onthewayandimreached.class);
                        intent.putExtra("message", message);
                        intent.putExtra("BookingIdT", BookingIdT);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);

                    }
                });
            } else if (title != null && title.equals("Reached")) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Intent intent = new Intent(MyFirebaseMessaging.this, Onthewayandimreached.class);
                        intent.putExtra("message", message);
                        intent.putExtra("BookingIdT", BookingIdT);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(intent);

                    }
                });
            }

        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    private void showArrivedNotifAPI26(String body) {
        PendingIntent contentIntent = PendingIntent.getActivity(getBaseContext(), 0,
                new Intent(), PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationHelper notificationHelper = new NotificationHelper(getBaseContext());
        Notification.Builder builder = notificationHelper.getUberNotification("Arrived", body, contentIntent, defaultSound);
        notificationHelper.getManager().notify(1, builder.build());

    }

    private void openRateactivity(String body) {

        Intent intent = new Intent(this, RateActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }

    private void showArrivedNotif(String body) {
        PendingIntent contentIntent = PendingIntent.getActivity(getBaseContext(), 0,
                new Intent(), PendingIntent.FLAG_ONE_SHOT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext());
        builder.setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
                .setWhen(System.currentTimeMillis()).
                setSmallIcon(R.drawable.ic_menu_camera)
                .setContentTitle("Arrived")
                .setContentText(body)
                .setContentIntent(contentIntent);

        NotificationManager manager = (NotificationManager) getBaseContext().getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(1, builder.build());
    }

}

MyFirebaseIdService

package com.example.praful.ubercoustomer.Service;

import com.example.praful.ubercoustomer.Common.Common;
import com.example.praful.ubercoustomer.Model.Token;
import com.example.praful.ubercoustomer.Common.Common;
import com.example.praful.ubercoustomer.Model.Token;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

public class MyFirebaseIdService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        super.onTokenRefresh();

        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        updateTokenToServer(refreshedToken);

    }

    private void updateTokenToServer(String refreshedToken) {

        FirebaseDatabase db =FirebaseDatabase.getInstance();
        DatabaseReference tokens = db.getReference(Common.token_table);

        Token token = new Token(refreshedToken);
        if(FirebaseAuth.getInstance().getCurrentUser() != null)
            tokens.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(token);

    }
}

【问题讨论】:

  • 请使用您的 FirebaseMessagingService#onMessageReceived 实施更新您的问题。
  • 请检查我有更新我的 MyFirebaseMessaging 类
  • 有什么想说的吗?
  • 检查我的答案,当 FCM 出于任何原因更新设备令牌时,请确保您实施 onTokenRefresh 并将刷新的令牌保存到您的数据库中。
  • @PrafulBuyakar Khaled Lela 的回答似乎是正确的。如果您打算取消 Google 的新数据库 Cloud Firestore,我已在我的 tutorials 之一中逐步说明,如何使用发送 notifications Cloud Firestore 和 Node.js。在这种情况下,Android Os 将为您处理通知。

标签: java android firebase firebase-cloud-messaging


【解决方案1】:
  • 首先检查此远程消息是否包含有效负载,可能是有效负载因任何原因而损坏。

    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    private static final String TAG = "REMOTE_MSG";
    
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        if (remoteMessage == null)
            return;
    
        // check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.e(TAG, "Notification body: " + remoteMessage.getNotification().getBody());
            createNotification(remoteMessage.getNotification());
        }
    
        // check if message contains a data payload
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "From: " + remoteMessage.getFrom());
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        }
    }
    
  • 不要在您的数据库中更新您的 FCM 设备令牌。

    public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService {
    private static final String TAG = "FCM_ID";
    
    @Override
    public void onTokenRefresh() {
        // get hold of the registration token
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        // lg the token
        Log.d(TAG, "Refreshed token: " + refreshedToken);
        sendRegistrationToServer(refreshedToken);
    }
    private void sendRegistrationToServer(String token) {
        // implement this method if you want to store the token on your server
    }
    }
    

更新 1

  • 如上所述Firebase repo issue 预计该问题与设备有关,请尝试其他设备方面。

更新 2 来自firebase repo 贡献者的引用 kroikie

如果应用被“杀死”或强制停止,FCM 不会处理消息。 当用户杀死一个应用程序时,这表明该用户没有 希望应用程序运行,以便应用程序在用户之前不运行 明确地再次启动它。

请注意,从最近列表中滑动应用程序不应“杀死”或强制 停下来。如果从最近刷卡后没有收到消息 列出然后请识别这些设备,我们将与 制造商来纠正这种行为。

只有当应用在前台时才能处理消息 或后台工作正常。

更新 3

  • 尝试在此问题上提到的 hack。

    1. 在 Manifest.xml 中插入这一行

      <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
      <uses-permission android:name="android.permission.WAKE_LOCK" />
      
    2. 这是因为打盹模式和电池优化,你只需要关闭所有应用程序或特定应用程序的电池优化。转到设置>>应用程序>>选择您的应用程序>>电池>> 电池优化>选择您的应用>>选择不优化。 问题解决了。

    3. 现在(对于 APP IS CLOSED 的情况)我将通知文本写入文件并在 extras == null 且 notificationText.txt 存在时读取此文本......它的愚蠢解决方案但它有效。当应用程序以其他方式关闭时,我怎样才能捕捉到这些额外内容。

更新 4

用户可以在设置>电池>中手动配置白名单 电池优化。或者,系统提供应用程序的方式 要求用户将他们列入白名单。

应用可以触发 ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS Intent 将用户直接带到电池优化,在那里他们可以 添加应用程序。持有 REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 的应用 权限可以触发系统对话框让用户将应用添加到 直接加入白名单,不用去设置。该应用程序触发 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 意图触发 对话。用户可以手动从白名单中删除应用程序 需要。

  • 以编程方式打开电池优化,检查此answer

注意这一点

在要求用户将您的应用添加到白名单之前,请确保 应用符合可接受的白名单用例。

注意: Google Play 政策禁止应用请求直接豁免 Android 6.0+ 中的电源管理功能(打盹和应用待机) 除非应用的核心功能受到不利影响。

更新 5

  • 从此answer查看PowerManager.isIgnoringBatteryOptimizations()

  • 当禁用电池优化时,考虑先检查它是否已经禁用然后不需要显示对话框,否则你可以显示对话框。

     /**
      * return false if in settings "Not optimized" and true if "Optimizing battery use"
      */
    private boolean checkBatteryOptimized() {
    final PowerManager pwrm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return !pwrm.isIgnoringBatteryOptimizations(getBaseContext().getPackageName());
        }
    }catch (Exception ignored){}
    return false;
    }
    
    private void startBatteryOptimizeDialog(){
     try {
    Intent intent = new Intent(android.provider.Settings.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:PUT_YOUR_PACKAGE_NAME_HERE"));
    startActivity(intent);
    
     } catch (ActivityNotFoundException e) {
       e.printStackTrace();
    }
    }
    

【讨论】:

  • 嗯,但我不认为这是原因,因为应用程序即使在被杀死后也会收到消息,但在 10 分钟后它不会。那是我的问题...任何方式感谢您的回复并询问您解决此问题的需要。任何事情都表示赞赏。
  • 检查我的答案更新,当 FCM 出于任何原因更新设备令牌时,请确保您实现 onTokenRefresh 并将刷新的令牌保存到您的数据库中
  • 即使应用程序被杀死,你能告诉 WhatsApp 是如何工作的吗?只是希望能得到一些线索...
  • 试试这个问题上提到的黑客。
  • 请查看我的Update 4,希望能帮助您解决问题。
猜你喜欢
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 2023-04-06
  • 2021-01-31
  • 2019-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
相关资源
最近更新 更多