使用 Kotlin 的 Firebase 云消息传递 Android
Firebase Cloud Messaging Android using Kotlin
我正在尝试将云消息(推送通知)从 firebase 控制台发送到我的应用程序。我在这里看到过类似的问题,但对我没有任何帮助。
我遵循了文档,观看了教程,在线搜索和 Whosebug,但似乎对我没有任何帮助。 MainActivity,我正在获取令牌并尝试使用它发送测试消息。
FirebaseInstanceId.getInstance().instanceId
.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "getInstanceId failed", task.exception)
return@OnCompleteListener
}
// Get new Instance ID token
val token = task.result?.token
// Log and toast
val msg = getString(R.string.msg_token_fmt, token)
Log.d(TAG, msg)
})
MyFirebaseMessagingService 类似于文档中的代码
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
Log.e(TAG, "From: ${remoteMessage.from}")
// Check if message contains a data payload.
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use WorkManager.
scheduleJob()
} else {
// Handle message within 10 seconds
handleNow()
}
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
sendNotification(it.body.toString())
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [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")
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token)
}
// [END on_new_token]
/**
* Schedule async work using WorkManager.
*/
private fun scheduleJob() {
// [START dispatch_job]
val work = OneTimeWorkRequest.Builder(MyWorkerActivity::class.java).build()
WorkManager.getInstance().beginWith(work).enqueue()
// [END dispatch_job]
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private fun handleNow() {
Log.d(TAG, "Short lived task is done.")
}
/**
* 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?) {
// TODO: Implement this method to send token to your app server.
Log.d(TAG, "sendRegistrationTokenToServer($token)")
}
/**
* 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_stat_sample_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_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
companion object {
private const val TAG = "MyFirebaseMsgService"
}
}
在我的 AndroidManifest 文件中有这个
<!-- [START firebase_service] -->
<service
android:name=".ui.services.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- [END firebase_service] -->
我看到了一个类似的问题,它有一个关于降级 firebase 消息传递依赖的答案,我也尝试过但没有成功。如果必须的话,我会 post 更多。非常感谢任何帮助,谢谢。
首先确保测试通知有效,在 onNewToken 中记录令牌并尝试手动发送它,确保您的软件 accept/receive 通知在后台运行。(打开设置并转到应用程序和通知。在该屏幕中,点击查看所有 X 个应用程序(其中 X 是您已安装的应用程序数量),然后点击 select 您的应用程序,并确保“背景 activity”已打开。
也试试这个,它适用于 me.I 希望它能有所帮助
依赖性:implementation 'com.google.firebase:firebase-messaging:20.2.0'
class MyFirebaseMessagingService : FirebaseMessagingService() {
val TAG = "FirebaseMessagingService"
@SuppressLint("LongLogTag")
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d(TAG, "msg received: ${remoteMessage.from}")
if (remoteMessage.notification != null) {
showNotification(remoteMessage.notification?.title, remoteMessage.notification?.body)
}
}
override fun onNewToken(token: String) {
Log.d("TAG", "Refreshed token: $token")
}
private fun showNotification(title: String?, body: String?) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT)
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, notificationBuilder.build())
}
}
原来我必须重新输入我的服务才能让它工作。我必须记住不要再复制和粘贴了。将它留在这里供将来遇到此问题的任何人使用。编码愉快!
class FCMService : FirebaseMessagingService() {
val TAG = "FCMService"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Log.d(TAG,"From: ${remoteMessage.from}")
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
if (true) {
scheduleJob()
}else {
handleNow()
}
}
remoteMessage.notification?.let {
Log.d(TAG, "Message notification body: ${it.body}")
sendNotification(it.body.toString())
}
}
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,
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_stat_sample_notification)
.setContentTitle(getString(R.string.fcm_message))
.setContentText(messageBody)
.setAutoCancel(false)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0, notificationBuilder.build())
}
override fun onNewToken(token: String) {
//super.onNewToken(token)
Log.d(TAG, token)
}
private fun handleNow() {
Log.d(TAG, "Short lived task done")
}
private fun scheduleJob() {
TODO("Not yet implemented")
}
}
<service
android:name=".ui.services.FCMService"
android:enabled="false"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
我正在尝试将云消息(推送通知)从 firebase 控制台发送到我的应用程序。我在这里看到过类似的问题,但对我没有任何帮助。 我遵循了文档,观看了教程,在线搜索和 Whosebug,但似乎对我没有任何帮助。 MainActivity,我正在获取令牌并尝试使用它发送测试消息。
FirebaseInstanceId.getInstance().instanceId
.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "getInstanceId failed", task.exception)
return@OnCompleteListener
}
// Get new Instance ID token
val token = task.result?.token
// Log and toast
val msg = getString(R.string.msg_token_fmt, token)
Log.d(TAG, msg)
})
MyFirebaseMessagingService 类似于文档中的代码
class MyFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
Log.e(TAG, "From: ${remoteMessage.from}")
// Check if message contains a data payload.
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use WorkManager.
scheduleJob()
} else {
// Handle message within 10 seconds
handleNow()
}
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
sendNotification(it.body.toString())
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [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")
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token)
}
// [END on_new_token]
/**
* Schedule async work using WorkManager.
*/
private fun scheduleJob() {
// [START dispatch_job]
val work = OneTimeWorkRequest.Builder(MyWorkerActivity::class.java).build()
WorkManager.getInstance().beginWith(work).enqueue()
// [END dispatch_job]
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private fun handleNow() {
Log.d(TAG, "Short lived task is done.")
}
/**
* 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?) {
// TODO: Implement this method to send token to your app server.
Log.d(TAG, "sendRegistrationTokenToServer($token)")
}
/**
* 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_stat_sample_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_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
companion object {
private const val TAG = "MyFirebaseMsgService"
}
}
在我的 AndroidManifest 文件中有这个
<!-- [START firebase_service] -->
<service
android:name=".ui.services.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- [END firebase_service] -->
我看到了一个类似的问题,它有一个关于降级 firebase 消息传递依赖的答案,我也尝试过但没有成功。如果必须的话,我会 post 更多。非常感谢任何帮助,谢谢。
首先确保测试通知有效,在 onNewToken 中记录令牌并尝试手动发送它,确保您的软件 accept/receive 通知在后台运行。(打开设置并转到应用程序和通知。在该屏幕中,点击查看所有 X 个应用程序(其中 X 是您已安装的应用程序数量),然后点击 select 您的应用程序,并确保“背景 activity”已打开。
也试试这个,它适用于 me.I 希望它能有所帮助
依赖性:implementation 'com.google.firebase:firebase-messaging:20.2.0'
class MyFirebaseMessagingService : FirebaseMessagingService() {
val TAG = "FirebaseMessagingService"
@SuppressLint("LongLogTag")
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d(TAG, "msg received: ${remoteMessage.from}")
if (remoteMessage.notification != null) {
showNotification(remoteMessage.notification?.title, remoteMessage.notification?.body)
}
}
override fun onNewToken(token: String) {
Log.d("TAG", "Refreshed token: $token")
}
private fun showNotification(title: String?, body: String?) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT)
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, notificationBuilder.build())
}
}
原来我必须重新输入我的服务才能让它工作。我必须记住不要再复制和粘贴了。将它留在这里供将来遇到此问题的任何人使用。编码愉快!
class FCMService : FirebaseMessagingService() {
val TAG = "FCMService"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Log.d(TAG,"From: ${remoteMessage.from}")
if (remoteMessage.data.isNotEmpty()) {
Log.d(TAG, "Message data payload: ${remoteMessage.data}")
if (true) {
scheduleJob()
}else {
handleNow()
}
}
remoteMessage.notification?.let {
Log.d(TAG, "Message notification body: ${it.body}")
sendNotification(it.body.toString())
}
}
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,
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_stat_sample_notification)
.setContentTitle(getString(R.string.fcm_message))
.setContentText(messageBody)
.setAutoCancel(false)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0, notificationBuilder.build())
}
override fun onNewToken(token: String) {
//super.onNewToken(token)
Log.d(TAG, token)
}
private fun handleNow() {
Log.d(TAG, "Short lived task done")
}
private fun scheduleJob() {
TODO("Not yet implemented")
}
}
<service
android:name=".ui.services.FCMService"
android:enabled="false"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>