Flutter集成Firebase Cloud Messaging(FCM)

Firebase Cloud Messaging

Firebase Cloud Messaging(FCM)是一种跨平台的消息传递解决方案,可以让您可靠地免费发送消息。android

使用FCM,您能够通知客户端应用程序能够同步新电子邮件或其余数据。您能够发送通知消息来推进用户的从新参与和保留。对于即时消息之类的用例,一条消息能够将最多4 KB的有效负载传输到客户端应用程序。ios

如下内容基于flutter 1.22.4版本git

准备工做

在开始以前,该文档假定您可以建立(或具备现有的)Flutter项目,而且还具备使用中的Firebase项目。若是您不知足这些先决条件,请参考准备工做github

安装

1.添加依赖项

dependencies:
  flutter:
    sdk: flutter
  firebase_core: "^0.5.3"
  firebase_messaging: "^8.0.0-dev.11"
复制代码

2.下载依赖项web

$ flutter pub get
复制代码

3. ios集成

参考:firebase.flutter.dev/docs/messag…shell

4. android集成

若是您正在使用Flutter Android Embedding V2(Flutter版本> = 1.12),则Android不须要其余集成步骤。—— 好比我。json

低版本请参考:Flutte接入firebase messagingapi

使用

在使用Firebase Cloud Messaging以前,您必须首先确保已初始化FlutterFire。bash

await Firebase.initializeApp();
复制代码

根据设备状态,传入消息的处理方式有所不一样。要了解这些状况以及如何将FCM集成到您本身的应用程序中,首先重要的是肯定设备能够处于的各类状态:服务器

状态 描述
Foreground 当应用程序打开时,且在前台显示时。
Background 打开应用程序时,可是在后台(最小化)。当用户按下设备上的“主页”按钮,经过应用程序切换器切换到另外一个应用程序或在其余选项卡(Web)上打开应用程序时,一般会发生这种状况。
Terminated 设备锁定或应用程序未运行时。用户能够经过设备上的应用程序切换器用户界面“将其刷掉”或关闭标签页(web)来终止应用程序。
  • 不论哪一种状况,该应用程序必须至少打开一次(以容许在FCM中注册,必需要能链接到谷歌)。

  • 在Android上,若是强行终止程序,那么是收不到推送的。

  • 在iOS上,若是用户从应用切换器上滑动了该应用程序,则必须再次手动将其从新打开,以使后台消息从新开始工做。

申请许可(ios,Mac和Web)

在iOS,macOS和Web上,必须先征询用户许可,而后才能在设备上接收FCM有效负载。

不须要在Android应用程序上请求权限。

代码:

FirebaseMessaging messaging = FirebaseMessaging.instance;

NotificationSettings settings = await messaging.requestPermission(
  alert: true,
  announcement: false,
  badge: true,
  carPlay: false,
  criticalAlert: false,
  provisional: false,
  sound: true,
);

print('用户授予权限结果: ${settings.authorizationStatus}');
复制代码

authorizationStatus属性能够返回一个值,该值可用于肯定用户的整体决策:

  • authorized: 用户已授予权限。
  • denied: 用户拒绝了权限。
  • notDetermined: 用户还没有选择是否授予许可。
  • provisional:用户授予了临时权限(请参阅[临时权限](firebase.flutter.dev/docs/messag…

在Android上,authorizationStatus始终是authorized。

NotificationSettings上的其余属性返回在当前设备上是启用,禁用仍是不支持特定权限。

有关更多信息,请查看Permissions文档。

处理消息

消息类型

根据应用程序的当前状态,传入的有效负载须要不一样的实现来处理它们:

Foreground Background Terminated
Notification onMessage onBackgroundMessage onBackgroundMessage
Data onMessage onBackgroundMessage (*see below*) onBackgroundMessage (*see below*)
Notification & Data onMessage onBackgroundMessage onBackgroundMessage

前台消息(Foreground)

默认状况下,在应用程序处于前台时到达的通知消息在Android和iOS上均不会显示可见的通知。可是,能够覆盖此行为:在前台收到推送时里用flutter_local_notifications来显示一条通知。

///前台消息
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('在前台收到消息!');

      if (message.notification != null) {
        RemoteNotification notification = message.notification;

        ///显示通知
        if (notification != null && notification.android != null) {
          FlutterLocalNotificationsPlugin().show(
              notification.hashCode,
              notification.title,
              notification.body,
              NotificationDetails(
                android: AndroidNotificationDetails(
                  channel.id,
                  channel.name,
                  channel.description,
									// TODO 向android添加适当的可绘制资源(在drawable下)
                  icon: 'launch_background',
                ),
              ),
              payload: message.data.toString());
        }
      }
    });
复制代码

后台消息(Background)

当前,在Android / Apple和基于Web的平台上处理后台消息的过程有所不一样。

在后台运行应用程序时处理消息有些不一样。能够经过onBackgroundMessage处理程序处理消息。

收到隔离信息后,就会生成隔离信息(仅适用于Android,iOS / macOS不须要单独的隔离信息,APNS真牛逼),即便您的应用程序未运行,也能够处理消息。

关于后台消息处理的方法,须要牢记如下几点:

  • 它不能是匿名函数。
  • 它必须是顶层函数(例如,不是须要初始化的类方法)。
static Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    print("收到后台消息: ${message.messageId}");
  }  

...
///后台消息
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
复制代码

收到后台消息的时候,运行长时间的繁重任务会影响设备性能,并可能致使操做系统终止该过程。若是任务运行时间超过30秒,则设备可能会自动终止该进程。

onMessageOpenedApp:当从后台状态打开应用程序时,该流会发送RemoteMessage。此时能够监听到用户对此种通知的点击行为:

///点击后台消息打开App
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('从后台打开!');
    });
复制代码

应用终止时点击通知打开App(Terminated)

onBackgroundMessage是没法监听到此种通知的行为的,可是能够接收到用户对此种通知的点击行为:

getInitialMessage():若是从终止状态打开应用程序,则将返回包含RemoteMessage的Future。一旦使用完毕,RemoteMessage将被删除。

///应用从终止状态打开
    var m = await FirebaseMessaging.instance.getInitialMessage();
    if (m != null) {
      print('应用从终止状态打开:${m?.notification?.title}');
    }
复制代码

要展现通知必须包含nofitication字段

处理交互

因为通知是可见的提示,所以用户一般会与通知进行交互(点击通知)。 Android和iOS上的默认行为是打开应用程序。若是应用程序终止,它将启动;若是它在后台,它将被带到前台。

firebase-messaging软件包提供了两种方法来处理此交互(上文一提到,再着重介绍下):

  • getInitialMessage():若是从终止状态打开应用程序,则将返回包含RemoteMessage的Future。一旦使用完毕,RemoteMessage将被删除。
  • onMessageOpenedApp:当从后台状态打开应用程序时,该流会发送RemoteMessage。

建议同时处理两种状况。

///点击后台消息打开App
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('从后台打开!');
    });

    ///应用从终止状态打开
    var m = await FirebaseMessaging.instance.getInitialMessage();
    if (m != null) {
      print('应用从终止状态打开:${m?.notification?.title}');
    }
复制代码

如下是官方示例:

class Application extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Application();
}

class _Application extends State<Application> {
  @override
  void initState() async {
    super.initState();

    // Get any messages which caused the application to open from
    // a terminated state.
    RemoteMessage initialMessage =
        await FirebaseMessaging.instance.getInitialMessage();

    // If the message also contains a data property with a "type" of "chat",
    // navigate to a chat screen
    if (initialMessage?.data['type'] == 'chat') {
      Navigator.pushNamed(context, '/chat',
          arguments: ChatArguments(initialMessage));
    }

    // Also handle any interaction when the app is in the background via a
    // Stream listener
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      if (message.data['type'] == 'chat') {
        Navigator.pushNamed(context, '/chat',
          arguments: ChatArguments(message));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Text("...");
  }
}
复制代码

处理交互的方式取决于您的应用程序设置,可是上面的示例显示了一个使用StatefulWidget的基本示例。

至于前台通知的点击,请查看flutter_local_notifications来设置.

主题

用户能够订阅一个主题,咱们发推送的时候对某一主题发出推送,订阅了这个主题的用户就会收到。

起到一个发送给多个用户推送的做用。

主要是我没找到经过http取到发推送的时候如何对全部用户发送。

订阅主题:

要订阅设备,请使用主题名称调用subscribeToTopic方法:

await FirebaseMessaging.instance.subscribeToTopic('weather');
复制代码

取消订阅主题

要取消订阅主题,请使用主题名称调用unsubscribeFromTopic方法:

await FirebaseMessaging.instance.unsubscribeFromTopic('weather');
复制代码

此处的意思是主题名称为weather.

经过Http发推送

若是您没法使用Firebase Admin SDK,则Firebase还支持经过HTTP, POST请求将消息发送到设备:

Authorization:服务器密钥

POST	https://fcm.googleapis.com/fcm/send 	HTTP/1.1

//请求头
Content-Type: application/json
Authorization: key={服务器密钥}

//body
{
	"to": "{fcmtoken}",
	"notification": {
		"icon": "juno_icon",
		"title": "本身的土",
		"body": "本身的地🤮",
		"sound": "default",
		"badge": 1,
		"content_available": true
	},
	"data": {
		"title": "本身的土",
		"body": "本身的地",
		"id": 1,
		"type": 2,
		"route": "ceceapp://main/fortune"
	}
}
复制代码

ios后台推送要添加content_available才能收到回调 相关文档

基于此写的示例项目已发布到github Android,ios 先后台的推送都已调通,多个手机测试过。

相关文章
相关标签/搜索