Java 服务器重置后无法通过firebase接收消息

Java 服务器重置后无法通过firebase接收消息,java,android,firebase,service,server,Java,Android,Firebase,Service,Server,我有一个移动应用程序,通过firebase云消息从服务器获取通知 当我启动移动应用程序并进行订阅时,移动应用程序收到来自服务器的通知 问题在于服务器停机并重新启动时。重置后,服务器会向移动应用发送通知(与之前的过程相同),但移动应用不会收到任何信息。请记住,移动应用程序同时保持不变(已注册)(服务器很快进行重置) 服务器的IP和端口保持不变 以下是订阅正确频道的手机代码: public class MainActivity extends AppCompatActivity { pr

我有一个移动应用程序,通过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);
}
@服务
公共类和IDPUSHNotificationsService{
私有静态最终字符串FIREBASE\u SERVER\u KEY=“XXXX”;
私有静态最终字符串FIREBASE\u API\u URL=”https://fcm.googleapis.com/fcm/send";
@异步的
公共可完成未来发送(HttpEntity){
RestTemplate RestTemplate=新RestTemplate();
ArrayList拦截器=新的ArrayList();
添加(新的HeaderRequestInterceptor(“授权”、“密钥=“+FIREBASE_服务器_密钥”);
add(新的HeaderRequestInterceptor(“内容类型”、“应用程序/json”);
restTemplate.setInterceptors(拦截器);
字符串firebaseResponse=restTemplate.postForObject(FIREBASE\u API\u URL,实体,String.class);
返回CompletableFuture.completedFuture(firebaseResponse);
}
重要提示:服务器启动时,服务器和移动应用程序之间的通信可以长时间工作


如何解决此问题?

我找到了解决此问题的方法

问题出在我的服务器上:我将
发送到:topic_name
而不是
发送到:token_from_server
,一旦应用程序上线且服务可用,则需要将
token_from_server
从移动应用程序发送到服务器(通过post请求)

此外,如果最后一个令牌将被更改,则移动应用程序需要向服务器发送新令牌(尽管我从未遇到过这种情况,但我已将此功能添加到我的移动应用程序和服务器映射中)


:)

在某些情况下,FCM可能无法传递消息。当消息太多(>100)时会发生这种情况

Firebase文档中说: onDeletedMessages()在FCM服务器删除挂起的消息时调用

这可能是由于:

  • FCM服务器上存储的邮件太多。当设备脱机时,应用服务器向FCM服务器发送一组不可折叠的邮件时,可能会发生这种情况
  • 该设备已很长时间未连接,应用服务器最近(在过去4周内)向该设备上的应用发送了一条消息