FCM数据消息无法正常工作 [英] FCM Data messages are not working properly

查看:116
本文介绍了FCM数据消息无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using data messages where we can send messages even when the app is killed or in background or in foreground. I am using FCM . But in my case sometimes my app does not get those messages . I am sending messages from app to app. Sometimes the app get messages even when it is killed or removed from background but again , sometimes it wont. When i open the app , then suddenly the message appears. I am opening activities when a particular message is received . I know that data messages are used for sending messages even when the app is killed or in background or in foreground , but i am having problem like this . please help !.. I want it to be absolute . I just want my app to be connected to FirebaseMessagingServices always , even when it is killed. I don't know about services and some says that i need to create a foreground services . How to create it and implement to 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);

    }
}

推荐答案

  • 首先检查此远程消息是否包含有效负载,可能是有效负载由于任何原因而损坏.

    • First check this remote message contains payload, May be payload get corrupt for any reason.

      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设备令牌.

    • DON'T forgent to update your FCM device token on your DB.

      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

      • As mentioned Firebase repo issue expected that issue to be related to device, Please try another device aspect.

      更新2 firebase存储库贡献者 kroikie

      如果某个应用被杀死"或被强行停止,FCM不会处理消息. 当用户杀死某个应用程序时,表明该用户没有 希望该应用程序运行,以便该应用程序直到用户运行 明确地再次启动它.

      FCM does not process messages if an app is "killed" or force stopped. When a user kills an app it is an indication that the user does not want the app running so that app should not run till the user explicitly starts it again.

      请注意,从最新消息"列表中滑动应用程序不应杀死"或强行使用 停下来.如果从最新消息中刷过后仍未收到邮件 列表,然后请识别这些设备,我们将与 制造商来纠正这种行为.

      Note that swiping an app from recents list should NOT "kill" or force stop it. If messages are not being received after swiping from recents list then please identify these devices and we will work with the manufactures to correct this behaviour.

      仅当应用程序处于前台时才能够处理消息 或背景正在按预期工作.

      Only being able to handle messages when the app is in the foreground or background is working as intended.

      更新3

      • 尝试在此问题上提及的骇客.

      1. 将此行插入Manifest.xml

      1. Inserting this lines in Manifest.xml

      <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
      <uses-permission android:name="android.permission.WAKE_LOCK" />
      

    • 这是因为DOZE模式和电池优化,您只需要关闭所有应用程序或特定应用程序的电池优化即可.转到设置>>应用>>选择您的应用>>电池>> 电池优化>选择您的应用>>选择不优化. 问题解决了.

    • It is because of DOZE mode and battery optimization,you just have to turn off battery optimization for all apps or particular app. Go to Settings>> apps >> select your app>> battery>> battery optimization> select your app>> select don't optimise. Problem solved.

      现在(对于APP IS CLOSED情况),我将Notification文本写入文件,如果extras == null且notificationText.txt存在,则读取此文本……这是愚蠢的解决方案,但它可以工作.当应用以其他方式关闭时,我该如何捕捉这些额外好处.

      Now (for APP IS CLOSED case) I write Notification text to file and read this text if extras == null and notificationText.txt is exists... its stupid solution but it works. How can I catch this extras when app is closed in other way.

    • 更新4

      • Try to Setting the priority of a message,
      • Disable Battery Optimization

      用户可以在设置">电池">手动"中配置白名单. 电池优化.另外,系统提供了应用程序的方法 要求用户将其列入白名单.

      Users can manually configure the whitelist in Settings > Battery > Battery Optimization. Alternatively, the system provides ways for apps to ask users to whitelist them.

      应用可以触发ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS目的 将用户直接带到电池优化,他们可以 添加应用.拥有REQUEST_IGNORE_BATTERY_OPTIMIZATIONS的应用 权限可以触发系统对话框,让用户将应用添加到 直接进入白名单,而无需进行设置.该应用会触发 ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS意图触发 对话.用户可以手动将应用从白名单中删除 需要.

      An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to take the user directly to the Battery Optimization, where they can add the app. An app holding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission can trigger a system dialog to let the user add the app to the whitelist directly, without going to settings. The app fires a ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent to trigger the dialog. The user can manually remove apps from the whitelist as needed.

      • 以编程方式打开电池优化",选中此 answer .
        • Programmatically open Battery Optimization, check this answer.
        • 注意这一点

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

          Before asking the user to add your app to the whitelist, make sure the app matches the acceptable use cases for whitelisting.

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

          Note: Google Play policies prohibit apps from requesting direct exemption from Power Management features in Android 6.0+ (Doze and App Standby) unless the core function of the app is adversely affected.

          更新5

          禁用电池优化时,请考虑首先检查其是否已已禁用,然后无需显示对话框,否则可以显示对话框.

          When disable battery optimization, Consider to check first if it's already disabled then no need to show dialog, else you can show dialog.

           /**
            * 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();
          }
          }
          

          这篇关于FCM数据消息无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆