Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Expandable Notification Show image when app is in background

I am implementing FCM notifications in Android, but how does notifications differ depending on the app status (background vs. foreground)?

see notifications image

I am sending the notification using the FCM API with Postman and this is the notification structure:

{ "notification": {       "title": "Notification title",       "body": "Notification message",       "sound": "default",       "color": "#53c4bc",       "click_action": "MY_BOOK",       "icon": "ic_launcher"    },    "data": {        "main_picture": "URL_OF_THE_IMAGE"      },    "to" : "USER_FCM_TOKEN" } 

The image to render is taken from data.main_picture.

I have implemented my own FirebaseMessagingService which makes the notifications display perfectly in foreground state. The notification code is the next:

NotificationCompat.BigPictureStyle notiStyle = new NotificationCompat.BigPictureStyle(); notiStyle.setSummaryText(messageBody); notiStyle.bigPicture(picture);  Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);  NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)             .setSmallIcon(R.drawable.ic_launcher)             .setLargeIcon(bigIcon)             .setContentTitle(title)             .setContentText(messageBody)             .setAutoCancel(true)             .setSound(defaultSoundUri)             .setContentIntent(pendingIntent)             .setStyle(notiStyle); code here  NotificationManager notificationManager =             (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notificationBuilder.build()); 

However, in background, the service is not even executed. In the AndroidManifest.xml, Firebase services are declared as follow:

<service     android:name=".MyFirebaseMessagingService">   <intent-filter>     <action android:name="com.google.firebase.MESSAGING_EVENT"/>   </intent-filter> </service>  <service     android:name=".MyFirebaseInstanceIDService">   <intent-filter>     <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>   </intent-filter> </service> 

My problem is not the LargeIcon or SmallIcon but displaying the big picture.

Thanks for your support.

like image 693
Fco. Javier Hernandez Garcia Avatar asked Jul 21 '16 12:07

Fco. Javier Hernandez Garcia


People also ask

How do you handle notifications when an app is in the background in Firebase web?

Firebase notifications behave differently depending on the foreground/background state of the receiving app. If you want foregrounded apps to receive notification messages or data messages, you'll need to write code to handle the onMessageReceived callback.

How do I show pictures in notification on flutter?

To achieve an image on local notification, first add the awesome_notifications Flutter package by adding the following lines in pubspec. yaml file. awesome_notifications is the best flutter package we got to show local notifications in the Flutter app.

How do I add a photo to a notification on Android?

To add an image in your notification, pass an instance of NotificationCompat. BigPictureStyle to setStyle() .


2 Answers

FCM notification messages don't support the largeIcon or bigPicture.

if you need them while in background you can use a FCM data message.

For data messages the onMessageReceived(message) method is always called, so you can use the message.getData() method and create your custom notification.

Read more about notification messages vs data messages here: https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

like image 160
Diego Giorgini Avatar answered Sep 20 '22 06:09

Diego Giorgini


See my FirebaseMessagingService

public class MyFirebaseMessagingService extends FirebaseMessagingService {       private static final String TAG = "FirebaseMessageService";     Bitmap bitmap;       /**      * Called when message is received.      *      * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.      */     @Override     public void onMessageReceived(RemoteMessage remoteMessage) {         // There are two types of messages data messages and notification messages. Data messages are handled         // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type         // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app         // is in the foreground. When the app is in the background an automatically generated notification is displayed.         // When the user taps on the notification they are returned to the app. Messages containing both notification         // and data payloads are treated as notification messages. The Firebase console always sends notification         // messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options         //         Log.d(TAG, "From: " + remoteMessage.getFrom());           // Check if message contains a data payload.         if (remoteMessage.getData().size() > 0) {             Log.d(TAG, "Message data payload: " + remoteMessage.getData());         }           // Check if message contains a notification payload.         if (remoteMessage.getNotification() != null) {             Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());         }           //The message which i send will have keys named [message, image, AnotherActivity] and corresponding values.         //You can change as per the requirement.                  //message will contain the Push Message         String message = remoteMessage.getData().get("message");         //imageUri will contain URL of the image to be displayed with Notification         String imageUri = remoteMessage.getData().get("image");         //If the key AnotherActivity has  value as True then when the user taps on notification, in the app AnotherActivity will be opened.          //If the key AnotherActivity has  value as False then when the user taps on notification, in the app MainActivity will be opened.          String TrueOrFlase = remoteMessage.getData().get("AnotherActivity");           //To get a Bitmap image from the URL received         bitmap = getBitmapfromUrl(imageUri);           sendNotification(message, bitmap, TrueOrFlase);       }         /**      * Create and show a simple notification containing the received FCM message.      */       private void sendNotification(String messageBody, Bitmap image, String TrueOrFalse) {         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);           Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);         NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)                 .setLargeIcon(image)/*Notification icon image*/                 .setSmallIcon(R.drawable.firebase_icon)                 .setContentTitle(messageBody)                 .setStyle(new NotificationCompat.BigPictureStyle()                         .bigPicture(image))/*Notification with Image*/                 .setAutoCancel(true)                 .setSound(defaultSoundUri)                 .setContentIntent(pendingIntent);           NotificationManager notificationManager =                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);           notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());     }       /*     *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 33
Arpit Patel Avatar answered Sep 22 '22 06:09

Arpit Patel