Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Save FCM Notification to Room DB

I am using firebase FCM to get the notification. I want if the notification received, that should store in my RoomDatabase. Later on, when the user opens the app, then in notification section all notification will display.

I am using MVVM, I was trying to save through ViewModel but it not work. Here is my present code.

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;

        }
    }}
like image 861
Akash Chaubey Avatar asked Mar 04 '23 03:03

Akash Chaubey


1 Answers

You could use Postman to send the message instead of the firebase console. So the onMessageReceived() method is called always even if the app is on background or foreground. You should subscribe your app to an FCM topic at the MainActivity and send the JSON message from the Postman.

Send FCM Messages using Postman

After that in onMessageReceived(), you could save the message data to the room DB.

Here's an Example. I do it in my app like this

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

My JSON Request from Postman

{
    "to" : "/topics/sathyanga",
    "collapse_key" : "type_a",
    "data" : {
        "body" : "Notification Body",
        "title": "Notification Title",
        "type" : "review",//Custom Data
        "itemId" : "Item5"//Custom Data
    }
}

Using it like this we can ensure that the receive FCM is always a data message. So it will run even if the app is not in the foreground.

like image 141
Yasiru Nayanajith Avatar answered Mar 16 '23 23:03

Yasiru Nayanajith