В своем приложении чата я использую 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()
}
}
}
}
В чем проблема и почему я не получаю сообщения все время?