我正在尝试"捕捉"发送到应用程序的firebase云消息,当我收到(/点击(一条消息时,我想根据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:问题是由谷歌的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
根据您的问题,我可以猜测您正在接收数据消息
@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());
}
}
}
应用程序构建.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
公共类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>
FirebaseMessagingService类
@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时也能正常工作。有关邮件类型的更多信息,请点击此处。
TL;DR:只有当应用程序处于前台时,数据消息才会触发甚至总是通知消息。
我不知道是什么导致了这个问题,但我已经在GitHub上创建了一个关于它的问题,所以也许它会在未来得到修复。