一段时间后或重新启动后未收到FCM推送通知



我有一个小问题,不幸的是,我目前无法独自解决,所以在这里寻求帮助。

我正在尝试在我的应用程序中构建推送通知,我正在使用FCM。对于整个过程,我使用:

  • 带有firebase的Android应用程序
  • 发送FCM推送通知的PHP脚本
  • MySQL数据库存储令牌

它的工作方式如下:每次生成新的令牌时,我都会将此令牌发送到MySQL数据库,然后将其存储在那里。我有一个PHP脚本,它读取数据库中所有可以找到的令牌,并向所有设备发送推送通知。

我看了很多youtube视频,读了很多关于如何做到这一点的文章,我设法让它工作起来,然而,它非常不稳定,我无法让它持续工作。

以下是一些由于我未知的原因而不起作用的场景。

案例1:

  • 第1天:我只是安装了应用程序,启动了它,然后把它放在后台。发送推送并成功接收。3-4小时后,我再次发送通知并成功收到
  • 第二天:就在第一天之后,第二天凌晨1点,我再次发送通知,但一直没有收到。我上床睡觉了,第二天早上消息一直没有收到,所以我尝试再次发送消息,我的php脚本说消息已经收到(根据Firebase控制台响应(,但通知从未显示

注意:我还在";onMessageReceived(("将消息保存到MySQL,这样我就可以亲自监控设备是否至少收到了消息,以更好地了解它是如何工作的,但设备甚至从未收到过。

案例2:

  • 第1天:安装应用程序。启动它,关闭它并发送推送。已成功接收。1小时后,我重新启动手机。20分钟后,我尝试发送推送,但一直没有收到。我尝试启动应用程序并将其放在后台,但仍然一无所获。我试着不是用PHP脚本,而是用FCM控制台发送一些通知,但仍然没有。仅仅过了10分钟,我就收到了一段时间前发送的通知,但我尝试用我的PHP脚本发送通知,但它仍然不起作用,只有过了几分钟,我才能再次用我的PHP发送通知

我上面描述的行为在我的理解中是非常混乱的。我不遵循任何逻辑。

我的代码:

PHP脚本:

<?php 
function send_notification ($tokens, $data, $priority)
{
$url = 'https://fcm.googleapis.com/fcm/send';
$fields = array(
'delay_while_idle' => false,
'android' => $priority,
'data' => $data,
'registration_ids' => $tokens
);
//var_dump($fields);
$headers = array(
'Authorization: key = KJAdkashdkhaiiwueyIhAXZ.....',
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);  
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);

print($ch);
print("<br>");
print("<br>");
print($result);
print("<br>");
print("<br>");
print(json_encode($fields));
print("<br>");
print("<br>");

if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
$conn = mysqli_connect('ip_address', 'username', "password", 'mydatabasename');
$sql = "SELECT TOKEN FROM users";
$result = mysqli_query($conn,$sql);
$tokens = array();
if(mysqli_num_rows($result) > 0 ){
while ($row = mysqli_fetch_assoc($result)) {
$tokens[] = $row["TOKEN"];
}
}
mysqli_close($conn);
$data = array(
'title' => 'This is title of the message',
'body' => 'This is body of the message',
'contents' => 'Simple contents of the message'
);
$android = array(
'priority' => 'high'
);
$message_status = send_notification($tokens, $data, $android);
echo $message_status;

安卓:

MyFirebaseMessagingService

class MyFirebaseMessagingService : FirebaseMessagingService() {
/**
* Called when message is received.
*
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// Save received message to MySQL
HUC.success()
// Check if message contains a data payload.
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
}
// Send notification containing the body of data payload
sendNotification(remoteMessage.data["body"].toString())
}
// [END receive_message]
// [START on_new_token]
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")

// Saving my registration token to MySQL
sendRegistrationToServer(token)
}
// [END on_new_token]
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private fun sendRegistrationToServer(token: String?) {
CoroutineScope(IO).launch {
// HttpURLConnection function to save token to MySQL
val response = HUC.saveToken(token)
withContext(Main){
Log.d(TAG, "Server response: $response")
}
}
}
/**
* Create and show a simple notification containing the received FCM message.
*
* @param messageBody FCM message body received.
*/
private fun sendNotification(messageBody: String) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT
)
val channelId = getString(R.string.default_notification_channel_id)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(getString(R.string.fcm_message))
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
companion object {
private const val TAG = "MyFirebaseMsgService"
}
}

请帮我理解这里。也许我做错了什么,也许我错过了什么。

事实上,当我硬重置手机时,一切都开始正常工作,这让我相信这是内部手机问题,而不是我的实现。

最新更新