Android: Сохранить уведомление FCM в Room DB - PullRequest
1 голос
/ 19 апреля 2019

Я использую 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;

        }
    }}

Ответы [ 2 ]

3 голосов
/ 19 апреля 2019

Вы можете использовать Почтальон для отправки сообщения вместо консоли Firebase.Поэтому метод onMessageReceived () вызывается всегда, даже если приложение находится в фоновом режиме или на переднем плане. Вы должны подписать свое приложение на тему FCM в MainActivity и отправить сообщение JSON от Почтальона.

Отправка сообщений FCM с помощью Почтальона

После этого в onMessageReceived () вы можете сохранить данные сообщения в БД комнаты.

Вот пример.Я делаю это в своем приложении следующим образом:

Мой 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всегда сообщение данных.Так что он будет работать, даже если приложение не на переднем плане.

0 голосов
/ 19 апреля 2019

Вы должны получить доступ к вашей базе данных прямо из вашего сервиса. Это не деятельность или фрагмент, поэтому вы не сможете создать экземпляр ViewModel.

Рассмотрите возможность создания отдельного репозитория Singleton, который будет точкой доступа для вашей БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...