Не могу получать сообщения через firebase после перезагрузки сервера - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть мобильное приложение, которое получает уведомления от сервера через облачную систему Firebase .

Когда я запускаю мобильное приложение и выполняю подписку, мобильное приложение получило уведомление от сервера.

Проблема в том, что сервер отключается и выполняет перезагрузку . После этого сброса сервер отправляет мобильному приложению уведомление (с той же процедурой, что и раньше), но мобильное приложение ничего не получает. Помните, что мобильное приложение пока остается прежним (зарегистрированным) (сервер очень быстро выполняет сброс).

IP и порты сервера остаются прежними ...

Вот мобильный код для подписки на нужный канал:

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

А вот на моем сервере процедура отправки уведомления:

@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);
}

ВАЖНО: при работающем сервере связь между сервером и мобильным приложением может работать долгое время ...

Как мне решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

В некоторых ситуациях FCM может не доставить сообщение. Это происходит, когда слишком много сообщений (> 100)

В документации Firebase говорится: onDeletedMessages () вызывается, когда сервер FCM удаляет ожидающие сообщения.

Это может быть связано с:

  1. Слишком много сообщений хранится на сервере FCM. Это может произойти, когда серверы приложения отправляют кучу неразборных сообщений на серверы FCM, когда устройство находится в автономном режиме.
  2. Устройство долгое время не подключалось, и сервер приложений недавно (в течение последних 4 недель) отправил сообщение приложению на этом устройстве.
0 голосов
/ 04 мая 2018

Я нашел решение для этого.

Проблема была на моем сервере: я отправил to: topic_name вместо to: token_from_Server, где token_from_server нужно отправить из мобильного приложения (через почтовый запрос) на сервер, как только приложение выйдет в эфир и услуга становится доступной.

Кроме того, мобильное приложение должно отправить серверу новый токен, если последний изменится (хотя со мной этого никогда не случалось, я добавил эту функцию в свое мобильное приложение и для этого сопоставил сервер).

:)

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