MyFirebaseMessagingService.onMessageReceived() 不起作用

MyFirebaseMessagingService.onMessageReceived() does not work

我正在尝试 "catch" 将 firebase 云消息发送到应用程序,当我收到(/单击)消息时,我想根据添加的 "Custom data" key/value 执行某些操作在 firebase 控制台中。

我现在的代码如下所示:

MyFirebaseMessagingService:

package com.company.app;

import android.util.Log;

import androidx.annotation.NonNull;

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

import java.util.Map;

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "Notification";

    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        Log.i(TAG, "Receiving notification...");
        for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            Log.d(TAG, "key, " + key + " value " + value);
        }
    }
}

AndroidManifest.xml:

        ...

        <!-- Firebase notification -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">

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

    </application>

build.gradle(模块:应用程序):

dependencies {

    //Google firebase
    implementation 'com.google.firebase:firebase-analytics:17.2.1'
    implementation 'com.google.firebase:firebase-messaging:20.0.1'

    ...

我的猜测是 <service android:name=".MyFirebaseMessagingService" android:exported="false"> 没有被执行,但我不明白为什么。 我没有收到任何错误。 除此之外,我的通知没有任何问题。

如果有帮助的话,这里是控制台日志:

D/FA: Logging event (FE): notification_receive(_nr), 
Bundle[{
 ga_event_origin(_o)=fcm,
 message_device_time(_ndt)=0,
 message_type(_nmc)=display,
 message_name(_nmn)=B1 - TN18,
 message_time(_nmt)=1574177464,
 message_id(_nmid)=8950284200210511319}]

有什么想法吗?

编辑:相同的代码在一个空的应用程序中工作

编辑 2:问题是由 google 的 TWA LauncherActivity

引起的

编辑 3:

public class LauncherActivityTWA extends AppCompatActivity {

private TwaLauncher mTwaLauncher;
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    this.mTwaLauncher.launch(getLaunchingUrl()); //this is causing the issue
}

编辑 4:现在我已经通过切换到 WebView 解决了这个问题,稍后我将尝试让它与 TWA 一起工作。我仍然认为这个问题是由 TWA 或与之相关的一些库引起的

编辑 5:所以我找到了一种解决方法 - 如果您想同时继续使用 TWA 和 FCM,您将不得不只使用数据消息,通知消息似乎不会触发 onMessageReceived 即使应用程序处于前台

From your question, I can guess you are receiving Data Message

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (remoteMessage == null)
        return;
    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        handleNotification(remoteMessage.getNotification().getBody());
    }
    // Check if message contains a data payload.
    if (remoteMessage.getData().size() > 0) {
        String title = "", body = "", type = "";
        Intent hIntent = new Intent(getApplicationContext(), HomePageActivity.class);
        try {
            for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) 
               {
                String key = entry.getKey();
                String value = entry.getValue();
                CommonUtils.logThis(TAG, "key, " + key + " value " + value);
                switch (key) {
                    case "title":
                        title = entry.getValue();
                        break;
                    case "body":
                        body = entry.getValue();
                        break;
                    case "type":
                        type = entry.getValue().toLowerCase();
                        break;
                }
            }
            CommonUtils.logThis("jeev", "Type is : " + type);
            switch (type) {
                case "your_notification_type":
                    //write your code here
                    break;
            }
        } catch (Exception e) {
            CommonUtils.logThis(TAG, "Exception: " + e.getMessage());
        }
    }
}

应用build.gradle

implementation 'com.google.firebase:firebase-core:11.6.0'
implementation 'com.google.firebase:firebase-messaging:11.6.0'here

Menifest.xml

 <service android:name=".Notification.MyFirebaseInstanceIdService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".Notification.MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/app_icon" />

MyFirebaseMessagingService.Java

public class MyFirebaseMessagingService 扩展了 FirebaseMessagingService {

private static final String TAG = "notifi";
NotificationChannel mChannel;
String CHANNEL_ID="1234";

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);




    Intent intent = new Intent(this,MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_ONE_SHOT);

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mChannel = new NotificationChannel(CHANNEL_ID, "Name", NotificationManager.IMPORTANCE_HIGH);
        mChannel.setLightColor(Color.GRAY);
        mChannel.enableLights(true);
        mChannel.enableVibration(true);
        mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500});
        mChannel.setDescription("desc");
        AudioAttributes audioAttributes = new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                .build();
        mChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, audioAttributes);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel( mChannel );
        }
    }

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
    notificationBuilder.setContentTitle("MY Notification");
    notificationBuilder.setContentText(remoteMessage.getNotification().getBody());
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setSmallIcon(R.drawable.app_icon);

    //Vibration
    notificationBuilder.setVibrate(new long[] { 1000, 1000, 1000, 1000, 1000 });
    //LED
    notificationBuilder.setLights(Color.RED, 3000, 3000);

    //Ton
    notificationBuilder.setSound(Settings.System.DEFAULT_NOTIFICATION_URI);

    notificationBuilder.setPriority(Notification.PRIORITY_MAX);
    notificationBuilder.setContentIntent(pendingIntent);
    notificationManager.notify(0,notificationBuilder.build());







}


private void sendNotification(RemoteMessage.Notification notification, Map<String, String> data) {
    Bitmap icon = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);

    Intent intent = new Intent(this, MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);

    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id")
            .setContentTitle(notification.getTitle())
            .setContentText(notification.getBody())
            .setAutoCancel(true)
            .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
            .setContentIntent(pendingIntent)
            .setContentInfo(notification.getTitle())
            .setLargeIcon(icon)
            .setColor(Color.RED)
            .setLights(Color.RED, 1000, 300)
            .setDefaults(Notification.DEFAULT_VIBRATE)
            .setSmallIcon(R.mipmap.ic_launcher);


    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // Notification Channel is required for Android O and above
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

        NotificationChannel channel = new NotificationChannel("channel_id", "channel_name", NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("channel description");
        channel.setShowBadge(true);
        channel.canShowBadge();
        channel.enableLights(true);

        channel.setLightColor(Color.WHITE);
        channel.enableVibration(true);
        channel.setVibrationPattern(new long[]{100, 200, 300, 400, 500});
        notificationManager.createNotificationChannel(channel);

    }

    notificationManager.notify(0, notificationBuilder.build());

   }


}

Manifest.xml

  <service
        android:name=".FirebaseNotification.FirebaseIDService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
        </intent-filter>
    </service>
    <service
        android:name=".FirebaseNotification.MyFirebaseMessagingService"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
</application>

FirebaseMessagingServiceclass

 @Override
 public void onMessageReceived(RemoteMessage remoteMessage) {

  // if (remoteMessage.getData().size() > 0) {
  // sendUserNotification(remoteMessage.getData().get("title"), r . 
  //emoteMessage.getData().get("text"));
  //}

    JSONObject json = null;
    try {
        json = new JSONObject(remoteMessage.getData().toString());
        //Log.e("JSON OBJECT", object.toString());
        JSONObject data = json.getJSONObject("data");
        String titel = data.getString("title");
        String message = data.getString("message");
        String image = data.getString("image");
        sendUserNotification(titel, message,image);
        //rest of the code
    } catch (Exception e) {
        e.printStackTrace();
    }


}


private void sendUserNotification(String title, String mess,String image) {
    Log.e("JSON title", title);
    Log.e("JSON mess", mess);
    int notifyID = 1;
    Intent intent;
    NotificationChannel mChannel;


    NotificationCompat.BigPictureStyle bpStyle = new NotificationCompat.BigPictureStyle();
    //bpStyle.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.fastfood)).build();
    bpStyle.bigPicture(getBitmapfromurl(image));


    Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    intent = new Intent(context, HomeActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    String CHANNEL_ID = context.getPackageName();// The id of the channel.
    CharSequence name = "Sample one";// The user-visible name of the channel.
    int importance = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        importance = NotificationManager.IMPORTANCE_HIGH;
    }
    NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID);
    notificationBuilder.setContentTitle(title);
    notificationBuilder.setAutoCancel(true);
    notificationBuilder.setPriority(Notification.PRIORITY_HIGH);
    notificationBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
    notificationBuilder.setContentIntent(pendingIntent);
    notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(mess));
    notificationBuilder.setContentText(mess);
    notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
    notificationBuilder.setSmallIcon(getNotificationIcon(notificationBuilder));
    notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
            R.mipmap.ic_launcher));
    notificationBuilder.setStyle(bpStyle);
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
        notificationManager.createNotificationChannel(mChannel);
    }
    if (notificationManager != null) {
        notificationManager.notify(notifyID /* ID of notification */, notificationBuilder.build());
    }


}



 public class FirebaseIDService extends FirebaseInstanceIdService {
 private static final String TAG = "FirebaseIDService";
 public static final String FIREBASE_TOKEN = "token";


@Override
public void onTokenRefresh() {
    // Get updated InstanceID token.
    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    //System.out.println("token=================="+refreshedToken);
    Log.i(TAG, "FCM Registration Token: " + refreshedToken);
    SharedPrefUtil.getInstance(this).put(FIREBASE_TOKEN,refreshedToken);

}

}

仅当收到的消息是通知消息时才会出现此问题。它可以按预期处理数据消息,即使是 TWA。有关消息类型的更多信息 here.

TL;DR: data messsages trigger the even always, notification messages only when app is in foreground.

我不知道是什么导致了这个问题,但我已经创建了一个关于它的 issue on GitHub,所以也许它将来会得到修复。