当前位置: 首页 > 知识库问答 >
问题:

Firebase消息服务不总是接收消息

姜彬郁
2023-03-14

在我的聊天应用程序中,每当用户收到新消息时,我使用FCM和Firebase功能发送通知。

为此,我有一个FirebaseMessagingService,它覆盖了onMessageReceived。除此之外,此服务还覆盖onNewToken。每当用户第一次启动应用程序时,就会调用onNewToken,我检索一个新令牌并将其存储在Firebase实时数据库中。

然后我去和一些用户聊天(不关闭应用程序)。当我收到新消息时,我会收到通知。调用onMessageReceived

问题是,当我关闭应用程序,然后打开它(或者关闭emulator,然后再次启动它),并且我从之前的聊天中收到一条新消息时,该服务不会被调用。我知道问题不在于Firebase函数,因为在我的控制台日志中,我收到了一条成功消息。

当我关闭并重新打开应用时,Firebase消息服务是否会停止?

以下是我Firebase消息服务的代码

class MyFirebaseInstanceId : FirebaseMessagingService() {

    private lateinit var sp: SharedPreferences
    private lateinit var auth: FirebaseAuth
    private lateinit var uid: String
    private lateinit var token: String



    override fun onMessageReceived(p0: RemoteMessage) {
        super.onMessageReceived(p0)
            if (p0.data.isNotEmpty()) {
            val payload: Map<String, String> = p0.data
            sendNotification(payload)
        }
    }

    override fun onNewToken(p0: String) {
        super.onNewToken(p0)
        // Save the new token
        sp = getSharedPreferences("AUTH_UID", Context.MODE_PRIVATE)
        token = p0
        auth = FirebaseAuth.getInstance()
        signIn()
    }


    private fun signIn() {
        auth.signInAnonymously().addOnCompleteListener { task ->
            if (task.isSuccessful) {
                uid = auth.currentUser?.uid.toString()
                sp.edit().putString("CURRENT_UID", uid).apply()
                sp.edit().putString("CURRENT_TOKEN", token).apply()
                FirebaseDatabase.getInstance().reference.child("users").child(uid).child("token")
                    .setValue(token)
                startActivity(
                    Intent(
                        this,
                        MainActivity::class.java
                    ).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                )
            }
        }
    }

    private fun sendNotification(payload: Map<String, String>) {

        createNotificationChannel()

        createNotification(payload)
    }

    private fun createNotification(payload: Map<String, String>) {
        val builder = NotificationCompat.Builder(this)
        builder.setSmallIcon(R.drawable.ic_message_not)
        builder.setContentTitle(payload["title"])
        builder.setContentText(payload["text"])
        builder.priority = NotificationCompat.PRIORITY_DEFAULT
        builder.setChannelId(Constants.CHANNEL_ID)

        val intent = Intent(this, MainActivity::class.java)
        val stackBuilder = TaskStackBuilder.create(this)

        stackBuilder.addNextIntent(intent)

        val resultPendingIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)

        builder.setContentIntent(resultPendingIntent)

        val notificationManager =
            (getSystemService(Context.NOTIFICATION_SERVICE)) as NotificationManager

        notificationManager.notify(0, builder.build())
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Create the NotificationChannel
            val name = getString(R.string.channel_name)
            val descriptionText = getString(R.string.channel_description)
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val mChannel = NotificationChannel(Constants.CHANNEL_ID, name, importance)
            mChannel.description = descriptionText
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(mChannel)
        }
    }
}

基本上,在我的飞溅活动中,我检查它是否是用户第一次打开应用程序。如果是,则从服务进行登录如果不是,则从Splash活动进行登录。

这是我的Splash活动的代码:

class SplashActivity : AppCompatActivity() {

    private lateinit var sp: SharedPreferences
    private lateinit var auth: FirebaseAuth
    private var flag: Boolean = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        // If it is first time user enters the app, wait for the MyFirebaseServiceId
        // If not, authenticate and sign in (since we already have the token)
        sp = getSharedPreferences("FIRST_LOGIN", Context.MODE_PRIVATE)
        flag = sp.getBoolean("IS_FIRST_TIME", true)
        if (!flag) {
            auth = FirebaseAuth.getInstance()
            signIn()
        }
        sp.edit().putBoolean("IS_FIRST_TIME", false).apply()


    }


    private fun signIn() {
        auth.signInAnonymously().addOnCompleteListener { task ->
            if (task.isSuccessful) {
                sp = getSharedPreferences("AUTH_UID", Context.MODE_PRIVATE)
                sp.edit().putString("CURRENT_UID", auth.currentUser?.uid).apply()

                getFCMToken()

                Handler().postDelayed({
                    startActivity(Intent(this, MainActivity::class.java))
                    finish()
                }, 2000)


            }
        }
    }

    private fun getFCMToken() {
        FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { p0 ->
            if (p0.isSuccessful) {
                val token = p0.result?.token.toString()
                //sp = getSharedPreferences("AUTH_UID", Context.MODE_PRIVATE)
                sp.edit().putString("CURRENT_TOKEN", token).apply()
            }
        }
    }

}

问题是什么?为什么我没有一直收到消息

共有1个答案

冯福
2023-03-14

我也面临同样的问题。这不是Android方面的错。您可以通过编辑通知模型/结构来解决此问题,不使用任何关键字作为表示通知的键、arry名称或对象名称。比如说通知{}===

注意:执行此操作后,您将不会收到通知或自动通知。您需要手动从该消息中获取数据,并使用notification manager创建自定义通知。在它的优先权和其他事情上加上标题。。。

这样做,您将解决在后台未收到通知的问题。如果你需要进一步的帮助,我可以帮忙。

 类似资料:
  • 我的应用程序在服务器上发生某种事件后接收推送通知。 除了在一小段时间内有许多事件一个接一个地发生的情况外,一切都很正常。 设备上的Firebase令牌也是正常的,因为应用程序从Firebase控制台接收通知。

  • 参考https://github.com/Azure/azure-service-bus/tree/master/samples/dotnet/gettingstart/microsoft.Azure.servicebus/basicsendreceiveusingtopicsubscriptionclient,我了解Azure服务总线主题的一般工作方式,我的问题更多地是关于它实际上是如何工作的。

  • 我希望以批处理模式接收来自Azure ServiceBus主题的消息。 阅读https://docs.microsoft.com/en-us/Azure/Azure-functions/functions-best-practices时指出: 我有一个方法: 这个方法是有效的,但它一次只需要一个消息。 根据Microsoft文档,我可以将其更改为: 注意:主题和订阅已启用“启用批处理操作”设置。

  • 我已经安装了一个XMPP服务器,并在android上使用smack做了一个客户端应用程序,一切都很好,但我正在更新的手机上测试应用程序,它不再工作了。 Android杀死了等待消息的服务(当用户关闭应用程序时杀死服务),我一直在读,人们说我应该使用FCM,但我想使用我自己的消息服务器,因为我在XMPP服务器上添加了一些特殊的用户管理逻辑。我不知道我是否可以使用FCM sdk来获取我自己的消息并从那

  • 我正在使用代码实现Azure服务总线主题,这些主题可以在以下位置找到:https://docs.microsoft.com/en-us/Azure/service-bus-messaging/service-bus-dotnet-how-to-use-topics-subscriptions 我尝试运行订阅者程序的两个实例,它包含以下方法: 但是,这不允许两个订户都接收消息,它接收的消息是两个订户

  • 根据MS文档,从订阅接收消息并不困难。但是,如果我希望我的应用程序在每次发布新消息时都接收一条消息--一个恒定的轮询。因此,使用了SubscriptionClient类的OnMessage()方法。 MS文档说:“...当调用OnMessage时,客户端启动一个内部消息泵,该消息泵不断轮询队列或订阅。该消息泵由发出Receive()调用的无限循环组成。如果调用超时,它发出下一个Receive()调