Сообщения не всегда принимаются службой сообщений Firebase - PullRequest
0 голосов
/ 21 февраля 2020

В своем приложении чата я использую FCM с Функции Firebase для отправки уведомлений, когда пользователь получает новое сообщение.

Для этого у меня есть FirebaseMessagingService , который переопределяет onMessageReceived. Помимо этого, эта служба также переопределяет onNewToken. Всякий раз, когда пользователь впервые запускает приложение , вызывается onNewToken, и я извлекаю новый токен и сохраняю его в базе данных реального времени Firebase .

I, а затем go общаться с каким-либо пользователем (без закрытия приложения). Когда я получаю новые сообщения, я получаю уведомление. Вызывается onMessageReceived.

Проблема в том, что когда я закрываю приложение, а затем открываю его (или выключаю эмулятор и снова запускаю его), и я получаю новое сообщение из того же предыдущего чата, услуга не вызывается . Я точно знаю, что проблема не в функциях 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)
        }
    }
}

По сути, в моем Spla sh Активность Я проверяю, первый ли раз пользователь открывает приложение. Если это так, то вход в систему осуществляется из Service , если это не так, вход в систему осуществляется из Spla sh Activity .

Это код для моего Spla sh Активность :

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 Ответ

0 голосов
/ 22 февраля 2020

Я столкнулся с той же проблемой. И это не вина android стороны. Вы можете решить эту проблему, отредактировав модель / структуру уведомлений, не используя ключевое слово в качестве ключа, имени массива или имени объекта с уведомлением. Допустим, уведомление {} ===> data {}

ПРИМЕЧАНИЕ: после этого вы не получите звуковое уведомление или уведомление Automati c. Вам необходимо вручную получить данные из этого сообщения и создать настраиваемое уведомление с помощью диспетчера уведомлений. Добавьте к этому приоритет и другие вещи ...

Делая это, вы решите проблему получения уведомления в фоновом режиме. Если вам нужна дополнительная помощь, я могу помочь.

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