【问题标题】:Android: Save FCM Notification to Room DBAndroid:将 FCM 通知保存到 Room DB
【发布时间】:2019-04-19 05:13:15
【问题描述】:

我正在使用 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;

        }
    }}

【问题讨论】:

    标签: android firebase-cloud-messaging android-sqlite android-room android-mvvm


    【解决方案1】:

    您可以使用 Postman 来发送消息,而不是使用 Firebase 控制台。因此,即使应用程序在后台或前台,也会始终调用 onMessageReceived() 方法。 You should subscribe your app to an FCM topic 在 MainActivity 并从 Postman 发送 JSON 消息。

    Send FCM Messages using Postman

    在 onMessageReceived() 之后,您可以将消息数据保存到房间数据库。

    这是一个例子。我在我的应用程序中这样做

    我的 FCM 服务

    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 始终是数据消息。因此,即使应用程序不在前台,它也会运行。

    【讨论】:

      【解决方案2】:

      您必须直接从您的服务访问您的数据库。它不是活动或片段,因此您将无法实例化 ViewModel。

      考虑创建一个单独的 Repository Singleton,它将成为您 DB 的访问点。

      【讨论】:

        猜你喜欢
        • 2017-05-04
        • 2017-07-01
        • 2017-01-12
        • 2017-02-03
        • 2018-09-04
        • 2019-12-20
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        相关资源
        最近更新 更多