个性化阅读
专注于IT技术分析

使用Firebase Cloud Messaging发送通知消息

在本节中, 我们将讨论当应用程序处于设备后台时, 如何从Notification Composer向开发设备发送测试通知消息。为此, 我们必须:

1)创建一个Firebase项目。

2)从助手或控制台将我们的应用程序连接到Firebase, 然后将google-services.json文件下载到我们的应用程序目录中。

3)在我们的项目级别build.gradle文件中, 确保在我们的buildscript和所有项目部分中都包含Google的Maven存储库。

使用Firebase Cloud Messaging发送通知消息

4)对于应用程序build.gradle文件, 我们有两个实现库”

  1. 将Cloud Messaging Android库和firebase核心库添加到我们的app / build.gradle文件中:’com.google.firebase:firebase-core:17.0.0’的实现’com.google.firebase:firebase-messaging:19.0的实现.1′
  2. 另外, 添加Google Play依赖项(并应用classpath):apply plugin:’com.google.gms.google-services’classpath’com.google.gms:google-services:4.2.0′
使用Firebase Cloud Messaging发送通知消息

5)编辑我们的应用清单

推荐并支持通知渠道。 FCM提供具有基本设置的默认通知渠道。如果要创建和使用默认通道, 则必须将default_notification_channel_id设置为通知通道对象的ID。当传入消息未明确设置通知通道时, FCM将使用此值:

<meta-data
	android:name="com.google.firebase.messaging.default_notification_channel_id"
	android:value="fcm_default_channel"/>

6)现在, 我们将移至主要活动, 以确保创建了通知渠道。

7)访问设备注册令牌

在我们的应用程序首次启动时, FCM SDK会为客户端应用程序实例生成一个注册令牌。如果要定位到单个设备, 则需要通过扩展FirebaseMessagingService并覆盖onNewToken来访问此令牌。首次启动后可以旋转令牌, 因此强烈建议检索最新的更新注册令牌。

注册令牌可能会更改:

  1. 应用删除实例ID的时间。
  2. 在新设备上还原应用程序时。
  3. 用户重新安装/卸载应用程序时。
  4. 用户清除应用程序数据时。
  5. 检索当前注册令牌

当我们需要检索当前令牌时, 调用FirebaseIntanceId.getInstance()。getInstanceId()。4

FirebaseInstanceId.getInstance().instanceId
	.addOnCompleteListener{task-?
		if(!task.isSuccessful){
			Log.w(TAG, "getInstanceId failed", task.exception)
			return@OnCompleteListener
		}
		//Getting new instance id token
	val token=task.result?.token
		
	 //toast and log 
		val msg1=getString(R.string.msg_token_fmt, token)

		Log.d(TAG, msg1)
		Toast.makeText(baseContext, msg1, Toast.Length_Short).show()
)}

9)监控令牌生成

生成新令牌时将触发oneNewToken回调。获取令牌后, 我们可以将其发送到我们的应用服务器并使用首选方法进行存储:

/**
* It is called if InstanceID token is modified(update). This may happen if the security of 
the previous token had been compromised. Essentially this is called when the InstanceID token
 is generated. 
*/
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")

        	// If we want to send messages to this application instance or
        	// manage the app's subscription on the server-side, send the
       	// Instance ID token to your app server.
        	sendRegistrationToServer(token)
    }

activity_main.xml

使用Firebase Cloud Messaging发送通知消息

Main_activity.kt

package com.example.firebasecloudmessaging

import android.app.NotificationChannel
import android.app.NotificationManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.messaging.FirebaseMessaging
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // Creating channel to show notifications.
            val channelId = getString(R.string.default_notification_channel_id)
            val channelName = getString(R.string.default_notification_channel_name)
            val notificationManager = getSystemService(NotificationManager::class.java)
            notificationManager?.createNotificationChannel(NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW))
        }

        // Any data accompanying the notification, if a notification message is tapped.
        // message is available in the intent extras. 
        // The launcher intent is triggered when the notification is tapped, so any accompanying data can         // be handled here. If we want a different intent fired, click_action// set the field of the notification message to the desired intent. The launcher intent
        // is used when no click_action is specified.
        //
        // Handle possible data accompanying notification message.
        intent.extras?.let {
            for (key in it.keySet()) {
                val value = intent.extras!!.get(key)
                Log.d(TAG, "Key: $key Value: $value")
            }
        }

        subscribeButton.setOnClickListener {
            Log.d(TAG, "Subscribing to my topic")
            FirebaseMessaging.getInstance().subscribeToTopic("myTopic")
                .addOnCompleteListener { task ->
                    var msg1 = getString(R.string.msg_subscribed)
                    if (!task.isSuccessful) {
                        msg1 = getString(R.string.msg_subscribe_failed)
                    }
                    Log.d(TAG, msg1)
                    Toast.makeText(baseContext, msg1, Toast.LENGTH_SHORT).show()
                }
        }

        logTokenButton.setOnClickListener {
            // Getting token
            FirebaseInstanceId.getInstance().instanceId
                .addOnCompleteListener(OnCompleteListener { task ->
                    if (!task.isSuccessful) {
                        Log.w(TAG, "getInstanceId failed", task.exception)
                        return@OnCompleteListener
                    }

                    // Getting new Instance ID token
                    val token = task.result?.token
                     // toast and Log                     val msg1 = getString(R.string.msg_token_fmt, token)
                    Log.d(TAG, msg1)
                    Toast.makeText(baseContext, msg1, Toast.LENGTH_SHORT).show()
                })
        }
    }

    companion object {
        private const val TAG = "MainActivity"
    }
}

MyFirebaseMessagingService.kt

package com.example.firebasecloudmessaging

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import androidx.annotation.NonNull
import androidx.core.app.NotificationCompat
import com.example.firebasecloudmessaging.MainActivity
import com.example.firebasecloudmessaging.R
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {

    /*** It is called when message is received.
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    override fun onMessageReceived(remoteMessage: RemoteMessage) {

//There are two types of messages, i.e., data messages and notification messages. //The data messages are handled here in onMessageReceived, either the app is in the foreground or background. 
//The data messages are traditionally used with GCM. 
//The notification messages are only received here in onMessageReceived when the app is in the foreground, and if the app is in the background, the automatically generated notification is displayed. 
//If the user taps on the notification, they are returned to the app. 
//Messages containing both notifications and data payloads are treated as notification messages. 
//The Firebase console always sends a notification message. 
//For more see: https://firebase.google.com/docs/cloud-messaging/concept-options

        // TODO(developer): Handle FCM messages here.
        Log.d(TAG, "From: ${remoteMessage?.from}")

        // Check if message contains a data payload.
        remoteMessage?.data?.isNotEmpty()?.let {
            Log.d(TAG, "Message data payload: " + remoteMessage.data)
        }

        // Check if message contains a notification payload.
        remoteMessage?.notification?.let {
            Log.d(TAG, "Message Notification Body: ${it.body}")
            sendNotification(it.body.toString())
        }

        // Also, if we intend on generating our own notifications as a result of a received FCM message, here is where that should be initiated. See the send notification method below.
    }

    /**
     * It called if InstanceID token is modified(update). This may happen if the security of      * the previous token had been compromised. This is essentially called when the InstanceID token* is generated, so this is where we would retrieve the token.
     */
    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")

        // If we want to send messages to this application instance or// manage this apps subscription on the server-side, send the// Instance ID token to our app server.
        sendRegistrationToServer(token)
    }

    /*** Preserve token to third-party servers.
     * Modify this method relate to 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 a token to your app server.
    }

    /**
     * Creating and showing 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 penIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT)

        val channelId = getString(R.string.default_notification_channel_id)
        val notificationBuilder = NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.ic_stat_ic_notification)
            .setContentTitle(getString(R.string.fcm_message))
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setContentIntent(penIntent)


        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(channelId, 1, notificationBuilder.build())
    }

    companion object {
        private const val TAG = "MyFirebaseMsgService"
    }
}

当我们单击“日志令牌”按钮时, 它为我们提供了一个InstanceID令牌, 我们在FCM控制台中使用它来发送消息。

现在, 我们将移至FCM控制台并单击“新建通知”。

单击Nee Notification后, 它将要求我们填写一些字段, 例如通知标题, 文本和图像等, 然后单击Select test message。

我们将粘贴复制的InstanceId令牌以添加FCM注册令牌字段, 然后单击“测试”。

最后一步在我们应用的通知栏中创建一条通知消息。仅当我们的应用程序将在后台运行时, 才会显示通知。


赞(0)
未经允许不得转载:srcmini » 使用Firebase Cloud Messaging发送通知消息

评论 抢沙发

评论前必须登录!