我正在使用Firebase FCM来获取通知。我希望如果收到通知,该通知应存储在我的RoomDatabase中。稍后,当用户打开应用程序时,所有通知都将显示在通知部分。
我正在使用MVVM,我试图通过 ViewModel 保存,但是它不起作用。这是我目前的代码。
public class MessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.d("MessagingService", s);
}
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// Check if message contains a notification payload.
if (remoteMessage.getData().isEmpty()){
showNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
} else {
showNotification(remoteMessage.getData());
}
}
private void showNotification(Map<String, String> data) {
Bitmap bitmap;
String title = data.get("title").toString();
String body = data.get("body").toString();
String imageUri = data.get("image").toString();
String TrueOrFalse = data.get("AnotherActivity").toString();
bitmap = getBitmapfromUrl(imageUri);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("AnotherActivity", TrueOrFalse);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
// LibraryViewModel libraryViewModel = ViewModelProviders.of(pendingIntent.get).get(HomeViewModel.class);
//Notification FCM
String NOTIFICATION_CHANNEL_ID = "vedicaim.com";
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "ArticleNotification",
NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("VedicAim Channel");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableLights(true);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.splash_logo)
.setContentTitle(title)
.setContentText(body)
.setSound(defaultSoundUri)
.setContentInfo("Info")
.setContentIntent(pendingIntent);
notificationManager.notify(new Random().nextInt(), notificationBuilder.build());
FirebaseMessaging.getInstance().subscribeToTopic("article")
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
String msg = "Successfull";
if (!task.isSuccessful()) {
msg = "Failed";
}
Log.d("MessagingService", msg);
}
});
}
private void showNotification(String title, String body) {
//Notification FCM
String NOTIFICATION_CHANNEL_ID = "vedicaim.com";
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "ArticleNotification",
NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("VedicAim Channel");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableLights(true);
notificationManager.createNotificationChannel(notificationChannel);
}
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.splash_logo)
.setContentTitle(title)
.setContentText(body)
.setContentInfo("Info");
notificationManager.notify(new Random().nextInt(), notificationBuilder.build());
FirebaseMessaging.getInstance().subscribeToTopic("article")
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
String msg = "Successfull";
if (!task.isSuccessful()) {
msg = "Failed";
}
Log.d("MessagingService", msg);
}
});
}
/*
*To get a Bitmap image from the URL received
* */
public Bitmap getBitmapfromUrl(String imageUrl) {
try {
URL url = new URL(imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(input);
return bitmap;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}}
答案 0 :(得分:3)
您可以使用Postman而不是Firebase控制台发送消息。因此,即使应用程序在后台或前台,也始终会调用onMessageReceived()方法。 documentation,然后从Postman发送JSON消息。
You should subscribe your app to an FCM topic
之后,您可以在onMessageReceived()中将消息数据保存到会议室DB。
这是一个例子。我是这样在我的应用中完成的
我的FCMService
public class FCMService extends FirebaseMessagingService {
private static final String DATABASE_NAME = "db_notification";
private static int NOTIFICATION_ID = 1;
private NotificationDatabase notificationDatabase;
private String body, title, itemId, type;
@Override
public void onNewToken(String s) {
super.onNewToken(s);
}
@Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
notificationDatabase = Room.databaseBuilder(getApplicationContext(),
NotificationDatabase.class, DATABASE_NAME)
.build();
if (!remoteMessage.getData().isEmpty()) {
Map<String, String> data = remoteMessage.getData();
title = data.get("title");
body = data.get("body");
itemId = data.get("itemId");
type = data.get("type");
Intent intent = new Intent(this, MainActivity.class);
if (type.equals("review")) {
intent.putExtra("itemId", itemId);
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
//Creating Notification
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this, "2")
.setSmallIcon(R.drawable.ic_notifications)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.notification_list))
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setStyle(new NotificationCompat.BigTextStyle().bigText(body))
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (NOTIFICATION_ID > 1073741824) {
NOTIFICATION_ID = 0;
}
Objects.requireNonNull(notificationManager).notify(NOTIFICATION_ID++, mNotifyBuilder.build());
//Saving to Room Database
new Thread(() -> {
Notification notification = new Notification();
notification.setNotificationTitle(title);
notification.setNotificationText(body);
notification.setItemId(itemId);
notification.setType(type);
notificationDatabase.notificationAccess().insertOnlySingleNotification(notification);
}).start();
}
}
}
邮递员的JSON请求
{
"to" : "/topics/sathyanga",
"collapse_key" : "type_a",
"data" : {
"body" : "Notification Body",
"title": "Notification Title",
"type" : "review",//Custom Data
"itemId" : "Item5"//Custom Data
}
}
使用这种方式,我们可以确保接收的FCM始终是数据消息。因此,即使应用程序不在前台,它也将运行。
答案 1 :(得分:0)
您必须直接从服务访问数据库。它不是活动或片段,因此您将无法实例化ViewModel。
考虑创建一个单独的存储库单例,它将作为您数据库的访问点。