在我的聊天应用程序中,每当用户收到新消息时,我使用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()
}
}
}
}
问题是什么?为什么我没有一直收到消息?
我也面临同样的问题。这不是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()调