Flutter消息推送插件firebase_messaging的使用
Flutter消息推送插件firebase_messaging的使用
Firebase Messaging Plugin for Flutter
这是一个Flutter插件,用于使用FCM(Firebase Cloud Messaging API)。要了解更多关于Firebase Cloud Messaging的信息,请访问Firebase网站
Getting Started
要开始使用Flutter的Firebase Cloud Messaging,请参考官方文档。
Usage 示例代码
下面是一个完整的示例应用,演示了如何在Flutter应用程序中使用firebase_messaging
插件:
import 'dart:async';
import 'dart:convert';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:http/http.dart' as http;
import 'firebase_options.dart'; // 请确保你已经配置了你的Firebase项目
// 定义一个顶级命名处理程序,用于处理后台/终止状态的消息。
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await setupFlutterNotifications();
showFlutterNotification(message);
print('Handling a background message ${message.messageId}');
}
// 创建一个Android通知通道用于高优先级的通知
late AndroidNotificationChannel channel;
bool isFlutterLocalNotificationsInitialized = false;
Future<void> setupFlutterNotifications() async {
if (isFlutterLocalNotificationsInitialized) {
return;
}
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.high,
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// 创建一个Android Notification Channel
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
// 更新iOS前景通知呈现选项以允许弹出通知
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
isFlutterLocalNotificationsInitialized = true;
}
void showFlutterNotification(RemoteMessage message) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: 'launch_background',
),
),
);
}
}
// 初始化FlutterLocalNotificationsPlugin包
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// 尽早设置后台消息处理程序
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
await setupFlutterNotifications();
}
runApp(MessagingExampleApp());
}
class MessagingExampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Messaging Example App',
theme: ThemeData.dark(),
routes: {
'/': (context) => Application(),
'/message': (context) => MessageView(),
},
);
}
}
// 简单计数器使消息唯一
int _messageCount = 0;
String constructFCMPayload(String? token) {
_messageCount++;
return jsonEncode({
'token': token,
'data': {
'via': 'FlutterFire Cloud Messaging!!!',
'count': _messageCount.toString(),
},
'notification': {
'title': 'Hello FlutterFire!',
'body': 'This notification (#$_messageCount) was created via FCM!',
},
});
}
class Application extends StatefulWidget {
@override
State<StatefulWidget> createState() => _Application();
}
class _Application extends State<Application> {
String? _token;
String? initialMessage;
bool _resolved = false;
@override
void initState() {
super.initState();
FirebaseMessaging.instance.getInitialMessage().then(
(value) => setState(
() {
_resolved = true;
initialMessage = value?.data.toString();
},
),
);
FirebaseMessaging.onMessage.listen(showFlutterNotification);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
});
}
Future<void> sendPushMessage() async {
if (_token == null) {
print('Unable to send FCM message, no token exists.');
return;
}
try {
await http.post(
Uri.parse('https://api.rnfirebase.io/messaging/send'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: constructFCMPayload(_token),
);
print('FCM request for device sent!');
} catch (e) {
print(e);
}
}
Future<void> onActionSelected(String value) async {
switch (value) {
case 'subscribe':
{
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test".',
);
await FirebaseMessaging.instance.subscribeToTopic('fcm_test');
print(
'FlutterFire Messaging Example: Subscribing to topic "fcm_test" successful.',
);
}
break;
case 'unsubscribe':
{
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test".',
);
await FirebaseMessaging.instance.unsubscribeFromTopic('fcm_test');
print(
'FlutterFire Messaging Example: Unsubscribing from topic "fcm_test" successful.',
);
}
break;
case 'get_apns_token':
{
if (defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS) {
print('FlutterFire Messaging Example: Getting APNs token...');
String? token = await FirebaseMessaging.instance.getAPNSToken();
print('FlutterFire Messaging Example: Got APNs token: $token');
} else {
print(
'FlutterFire Messaging Example: Getting an APNs token is only supported on iOS and macOS platforms.',
);
}
}
break;
default:
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cloud Messaging'),
actions: <Widget>[
PopupMenuButton(
onSelected: onActionSelected,
itemBuilder: (BuildContext context) {
return [
const PopupMenuItem(
value: 'subscribe',
child: Text('Subscribe to topic'),
),
const PopupMenuItem(
value: 'unsubscribe',
child: Text('Unsubscribe to topic'),
),
const PopupMenuItem(
value: 'get_apns_token',
child: Text('Get APNs token (Apple only)'),
),
];
},
),
],
),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
onPressed: sendPushMessage,
backgroundColor: Colors.white,
child: const Icon(Icons.send),
),
),
body: SingleChildScrollView(
child: Column(
children: [
MetaCard('Permissions', Permissions()),
MetaCard(
'Initial Message',
Column(
children: [
Text(_resolved ? 'Resolved' : 'Resolving'),
Text(initialMessage ?? 'None'),
],
),
),
MetaCard(
'FCM Token',
TokenMonitor((token) {
_token = token;
return token == null
? const CircularProgressIndicator()
: SelectableText(
token,
style: const TextStyle(fontSize: 12),
);
}),
),
ElevatedButton(
onPressed: () {
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
Navigator.pushNamed(
context,
'/message',
arguments: MessageArguments(message, true),
);
}
});
},
child: const Text('getInitialMessage()'),
),
MetaCard('Message Stream', MessageList()),
],
),
),
);
}
}
// UI组件,用于显示元数据
class MetaCard extends StatelessWidget {
final String _title;
final Widget _children;
MetaCard(this._title, this._children);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: const EdgeInsets.only(left: 8, right: 8, top: 8),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Container(
margin: const EdgeInsets.only(bottom: 16),
child: Text(_title, style: const TextStyle(fontSize: 18)),
),
_children,
],
),
),
),
);
}
}
此代码展示了如何集成和使用firebase_messaging
插件进行消息推送,并且包括了处理前台、后台和应用终止状态下的消息接收逻辑。通过flutter_local_notifications
插件实现了本地通知功能。为了使这个例子工作,你需要完成平台特定的设置和要求,并根据你的Firebase项目配置好相应的参数。
注意事项:
- 平台特定设置:遵循官方指南完成平台特定设置,如添加必要的依赖项到
build.gradle
文件中等。 - 服务端API Key:发送推送消息时使用的API Key需要从Firebase控制台获取。
- 设备Token:发送消息的目标设备Token可以通过
FirebaseMessaging.instance.getToken()
方法获得。 - 权限:确保应用拥有接收推送通知所需的权限。
- 测试环境:最好在真实设备上测试推送通知,因为模拟器可能不支持所有的推送特性。
更多关于Flutter消息推送插件firebase_messaging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter消息推送插件firebase_messaging的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用firebase_messaging
插件来实现消息推送的示例代码。这个示例将涵盖基本的配置和消息接收处理。
1. 添加依赖
首先,在pubspec.yaml
文件中添加firebase_messaging
依赖:
dependencies:
flutter:
sdk: flutter
firebase_core: ^1.10.0 # 确保也添加了firebase_core,用于Firebase初始化
firebase_messaging: ^11.2.0 # 使用最新版本
然后运行flutter pub get
来安装依赖。
2. 配置Firebase项目
在Firebase控制台中创建一个新的项目,并添加Flutter应用的包名。然后下载google-services.json
文件并将其放置在android/app/
目录下。对于iOS,你需要配置Runner/GoogleService-Info.plist
文件。
3. 初始化Firebase和Firebase Messaging
在main.dart
文件中,初始化Firebase和Firebase Messaging。
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Firebase Messaging Demo'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
@override
void initState() {
super.initState();
_configureFirebaseMessaging();
}
void _configureFirebaseMessaging() {
// 当应用在前台时接收到消息
_firebaseMessaging.onMessage.listen((RemoteMessage message) {
print('A new FCM message arrived!');
print('Message data: ${message.data}');
// 在这里可以显示本地通知或其他UI更新
_showLocalNotification(message.data);
});
// 当应用在后台时接收到消息(点击通知后触发)
_firebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A user tapped on a notification!');
print('Message data: ${message.data}');
});
}
Future<void> _showLocalNotification(Map<String, dynamic> message) async {
// 显示本地通知的代码(需要添加flutter_local_notifications依赖)
// 此处为示例,实际使用时请根据需要配置
}
@override
Widget build(BuildContext context) {
return Center(
child: Text('Firebase Messaging is configured!'),
);
}
}
4. (可选)显示本地通知
为了显示本地通知,你需要添加flutter_local_notifications
依赖,并在配置Firebase Messaging时调用它。
在pubspec.yaml
中添加依赖:
dependencies:
flutter_local_notifications: ^9.0.0 # 使用最新版本
然后在_MyHomePageState
类中配置本地通知:
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class _MyHomePageState extends State<MyHomePage> {
// ...
final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
var _initializationSettingsAndroid;
var _initializationSettingsIOS;
var _initializationSettings;
@override
void initState() {
super.initState();
_configureLocalNotifications();
_configureFirebaseMessaging();
}
Future<void> _configureLocalNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
_initializationSettingsAndroid = initializationSettingsAndroid;
// 对于iOS,请根据需要配置初始化设置
// const IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(
// requestAlertPermission: true,
// requestBadgePermission: true,
// requestSoundPermission: true,
// );
// _initializationSettingsIOS = initializationSettingsIOS;
// 统一初始化设置
_initializationSettings = InitializationSettings(
android: _initializationSettingsAndroid,
// iOS: _initializationSettingsIOS,
);
await _notificationsPlugin.initialize(_initializationSettings,
onSelectNotification: (String? payload) async {
if (payload != null) {
// 处理通知点击事件
print('Notification payload: $payload');
}
});
}
void _showLocalNotification(Map<String, dynamic> message) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your_channel_id', 'Your channel name', 'Your channel description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics);
await _notificationsPlugin.show(
0, // 通知ID
message['title'] ?? '',
message['body'] ?? '',
platformChannelSpecifics,
payload: jsonEncode(message),
);
}
// ...
}
请确保在Android项目中配置通知渠道(your_channel_id
),并在Firebase控制台中发送消息时包含title
和body
字段。
总结
上述代码展示了如何在Flutter应用中使用firebase_messaging
插件来接收和处理Firebase Cloud Messaging消息。通过结合flutter_local_notifications
插件,你还可以显示本地通知来通知用户。请确保在实际项目中根据需要进行进一步的配置和优化。