2

Notifications are not always received by my Android phones, even though Cloud Functions always sends them. As a useful side node: WhatsApp messages are always received (I tested it).

I noticed that notifications are received immediately when the phone is charging or when you open the app.

Also, the UID of the user is not always sent to the database even though a notification has been displayed (you'll understand what I mean by reading the code).

My question is: what can I change to receive notifications and then push to database all the time like it's supposed to be?

My notifications are of the "heads-up" type.

I've been trying to optimize my code for days with no success. I need help.

Code structure:

  1. When message is received, push UID of user to database to see how many people have been notified later.
  2. Send notification to user.

    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    
    // Firebase instance variables
    private FirebaseAuth mFirebaseAuth;
    private FirebaseUser mFirebaseUser;
    
    DatabaseReference myURL = FirebaseDatabase.getInstance().getReferenceFromUrl("https://newproj-54a87.firebaseio.com/notified");
    
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
    
        // Check if message contains a data payload.
        if (remoteMessage.getData() != null) {
    
            mFirebaseAuth = FirebaseAuth.getInstance();
            mFirebaseUser = mFirebaseAuth.getCurrentUser();
    
            if(mFirebaseUser != null)
                mUID = mFirebaseUser.getUid();
    
            myURL.push().setValue(mUID);
    
            sendNotification(remoteMessage.getData().get("body"), remoteMessage.getData().get("title"), remoteMessage.getData().get("icon"));
        }
    }
    
    private void sendNotification(String messageBody, String messageTitle, String iconURL) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);
        Bitmap bitmap = getBitmapFromURL(iconURL);
    
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setDefaults(DEFAULT_SOUND | DEFAULT_VIBRATE)
                .setPriority(Notification.PRIORITY_MAX)
                .setStyle(new NotificationCompat.BigTextStyle())
                .setSmallIcon(R.drawable.myIcon)
                .setLargeIcon(bitmap)
                .setContentTitle(messageTitle)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent);
    
        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }
    
    public Bitmap getBitmapFromURL(String strURL) { //from https://stackoverflow.com/a/16007659
        try {
            URL url = new URL(strURL);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
    }
    

My Cloud Function:

    const payLoad = {
    data:{
        title: name,
        body: body,
        icon: photoURL
        }
    };

    var options = {
        priority: "high",
        timeToLive: 1000
        };

        return admin.messaging().sendToTopic("notify", payLoad, options);

Please tell me if I forgot a piece of information. I'm running on a limited time schedule!

1 Answers1

4

If you are using Android 6.0 or versions above there is a feature called Doze that optimizes battery usage. When your phone is Idle (and it is not charging) it only receives high priority FCM notifications, and probably that's your case.

Android documentation says:

FCM is optimized to work with Doze and App Standby idle modes by means of high-priority FCM messages. FCM high-priority messages let you reliably wake your app to access the network, even if the user’s device is in Doze or the app is in App Standby mode. In Doze or App Standby mode, the system delivers the message and gives the app temporary access to network services and partial wakelocks, then returns the device or app to the idle state.

So if are using FCM data messages your backend should start sending the field "priority" : "high".
Ref: https://firebase.google.com/docs/cloud-messaging/concept-options

Juan Cruz Soler
  • 8,172
  • 5
  • 41
  • 44
  • Understanding the reason is the first step to solving a problem. **Thanks for clearing out the reason**. Now, it's time to solve the problem itself. –  Aug 15 '17 at 21:16