Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot receive messages through firebase after server reset

I have a mobile app that gets notifications from a server through firebase cloud messaging.

When I'm launching the mobile app and doing the subscription, the mobile app received the notification from the server.

The problem is when the server is going down and doing a restart. After this reset, the server is sending the mobile app the notification (with the same procedure as before), but the mobile app doesn't receive anything. Remember that the mobile app stays the same (registered) meanwhile (the server doing the reset very quickly).

The IP and ports of the server stays the same...

Here is the mobile code to subscribe the right channel:

public class MainActivity extends AppCompatActivity  {

    private static final String TAG = "MainActivity";

    private static final String NEW_CONTACTS_TOPIC = "new_contacts";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Create channel to show notifications.
            String channelId  = getString(R.string.default_notification_channel_id);
            String channelName = getString(R.string.default_notification_channel_name);
            NotificationManager notificationManager =
                    getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(new NotificationChannel(channelId,
                    channelName, NotificationManager.IMPORTANCE_LOW));
        }

        if (getIntent().getExtras() != null) {
            for (String key : getIntent().getExtras().keySet()) {
                Object value = getIntent().getExtras().get(key);
                Log.d(TAG, "Key: " + key + " Value: " + value);
            }
        }

        Button subscribeButton = findViewById(R.id.subscribeButton);
        subscribeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseMessaging.getInstance().subscribeToTopic(NEW_CONTACTS_TOPIC);

                // Log and toast
                String msg = getString(R.string.msg_subscribed);
                Log.d(TAG, msg);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });

        Button logTokenButton = findViewById(R.id.logTokenButton);
        logTokenButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Get token
                String token = FirebaseInstanceId.getInstance().getToken();

                // Log and toast
                String msg = getString(R.string.msg_token_fmt, token);
                Log.d(TAG, msg);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        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());
            try {
                handleNow(remoteMessage);
            } catch (IOException e) {
                Log.e(TAG, e.getMessage());
            } catch (InterruptedException e) {
                Log.e(TAG, e.getMessage());
            }
        }

        // Check if message contains a notification payload.
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }
    }
}

And here is the procedure within my server to send the notification:

@Service
public class AndroidPushNotificationsService {

private static final String FIREBASE_SERVER_KEY = "XXXX";
private static final String FIREBASE_API_URL = "https://fcm.googleapis.com/fcm/send";

@Async
public CompletableFuture<String> send(HttpEntity<String> entity) {

    RestTemplate restTemplate = new RestTemplate();

    ArrayList<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
    interceptors.add(new HeaderRequestInterceptor("Authorization", "key=" + FIREBASE_SERVER_KEY));
    interceptors.add(new HeaderRequestInterceptor("Content-Type", "application/json"));
    restTemplate.setInterceptors(interceptors);

    String firebaseResponse = restTemplate.postForObject(FIREBASE_API_URL, entity, String.class);

    return CompletableFuture.completedFuture(firebaseResponse);
}

IMPORTANT: while the server is up, the communication between the server and the mobile app can work for a long time...

How can I resolve this issue?

like image 843
Roni Koren Kurtberg Avatar asked Nov 07 '22 07:11

Roni Koren Kurtberg


1 Answers

In some situations, FCM may not deliver a message. This occurs when there are too many messages (>100)

In Firebase docs says: onDeletedMessages() called when the FCM server deletes pending messages.

This may be due to:

  1. Too many messages stored on the FCM server. This can occur when an app's servers send a bunch of non-collapsible messages to FCM servers while the device is offline.
  2. The device hasn't connected in a long time and the app server has recently (within the last 4 weeks) sent a message to the app on that device.
like image 107
Daniyar Kayirbolatov Avatar answered Nov 13 '22 01:11

Daniyar Kayirbolatov