import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_installations/firebase_installations.dart';
import 'package:flutter_udid/flutter_udid.dart';
import 'package:todoList_flutter/api/interceptor.dart';
import 'firebase_options.dart';
import 'dart:developer' as developer;
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:firebase_in_app_messaging/firebase_in_app_messaging.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:firebase_analytics/firebase_analytics.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in_dartio/google_sign_in_dartio.dart';
import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'local_notifications.dart';
// import 'interceptor.dart';
GetIt locator = GetIt.instance;
final ApiClient apiClient = locator<ApiClient>();
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
print("后台通知");
print("Handling a background message: ${message.messageId}");
print("title: ${message.notification?.title}");
print("body: ${message.notification?.body}");
print("payload: ${message.data}");
}
/// Requires that a Firebase local emulator is running locally.
/// See https://firebase.flutter.dev/docs/auth/start/#optional-prototype-and-test-with-firebase-local-emulator-suite
bool shouldUseFirebaseEmulator = false;
class FirebaseServers {
late final FirebaseApp app;
late final FirebaseAuth auth;
late final FirebaseInAppMessaging fiam;
late final FlutterLocalNotificationsPlugin localNoti;
FirebaseServers();
Future<dynamic> initializeFirebase() async {
app = await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// 在这里添加其他的初始化逻辑
auth = await setupFirebaseAuth(app);
fiam = await setupInAppMessaging();
// 初始化本地通知
localNoti = await setupLocalNotifications();
return {
'app': app,
'auth': auth,
'fiam': fiam,
'localNoti': localNoti,
};
}
Future<String> getNotificationToken() async {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
String? token = await _firebaseMessaging.getToken();
// 后台运行通知回调
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
// 前台运行通知监听
FirebaseMessaging.onMessage.listen(handleMessage);
// 监听 后台运行时通过系统信息条打开应用
FirebaseMessaging.onMessageOpenedApp.listen(onMessageOpenedApp);
// 如需在每次令牌更新时获得通知
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) {
// TODO: If necessary send token to application server.
print("FCM Token${fcmToken}");
// 每当生成新令牌时,都会触发此回调。
}).onError((err) {
print('FCM Token Error: $err');
// Error getting token.
});
return token!;
}
Future<String> getFirebaseInstallationId() async {
String installationId;
try {
installationId =
await FirebaseInstallations.id ?? 'Unknown installation id';
} on PlatformException {
installationId = 'Failed to get installation id.';
}
return installationId;
}
Future<FirebaseAuth> setupFirebaseAuth(FirebaseApp app) async {
FirebaseAuth auth;
auth = FirebaseAuth.instanceFor(app: app);
if (shouldUseFirebaseEmulator) {
await auth.useAuthEmulator('localhost', 9099);
}
if (!kIsWeb && Platform.isWindows) {
// await GoogleSignInDart.register(
// clientId: DefaultFirebaseOptions.currentPlatform.,
// );
}
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user == null) {
print('User is currently signed out!');
} else {
print('User is signed in!');
}
});
return auth;
}
Future<FirebaseInAppMessaging> setupInAppMessaging() async {
FirebaseInAppMessaging fiam = await FirebaseInAppMessaging.instance;
// fiam.setMessagesSuppressed(false);
// fiam.setAutoDisplayDefaultInAppMessage(true);
await fiam.setAutomaticDataCollectionEnabled(true);
print('In-App Messaging setup completed');
return fiam;
}
Future<FlutterLocalNotificationsPlugin> setupLocalNotifications() async {
// 初始化服务
FlutterLocalNotificationsPlugin localNoti =
await LocalNotificationsService().initialize();
developer.log('Local Notifications setup completed');
return localNoti;
}
void logEvent(String eventName, Map<String, dynamic> parameters) {
FirebaseAnalytics analytics = FirebaseAnalytics.instance;
analytics.logEvent(name: eventName, parameters: parameters);
}
void onMessageOpenedApp(RemoteMessage message) {
print("打开通知");
print("Handling a background message: ${message.messageId}");
print("title: ${message.notification?.title}");
print("body: ${message.notification?.body}");
print("payload: ${message.data}");
}
void handleMessage(RemoteMessage? message) {
// 如果消息不是空的话
if (message == null) return;
// 用户点击通知, 进入特定该页面
// Get.toNamed("/home", arguments: message);
print("前台通知");
print("title: ${message.notification?.title}");
print("body: ${message.notification?.body}");
print("payload: ${message.data}");
if (localNoti == null) {
print('Local Notifications Plugin is not initialized');
return;
}
// 显示通知
LocalNotificationsService().showNotification(
title: message.notification?.title ?? '',
body: message.notification?.body ?? '',
payload: message.data.toString(),
);
}
}
Future setupFirebase() async {
FirebaseServers firebaseServers = FirebaseServers();
final firebaseResult =
await firebaseServers.initializeFirebase(); // 在 setupFirebase() 中进行初始化
// 从返回的 Map 中提取值
final FirebaseApp firebaseApp = firebaseResult['app'];
final FirebaseAuth firebaseAuth = firebaseResult['auth'];
final FirebaseInAppMessaging firebaseInAppMessaging = firebaseResult['fiam'];
String? token = await firebaseServers.getNotificationToken();
String? installationId = await firebaseServers.getFirebaseInstallationId();
// 当token 获取到之后,通过调用接口将token 传递给后端
String udid = await FlutterUdid.consistentUdid;
developer.log(udid, name: '设备唯一标识符 - UDID');
developer.log(token, name: '${Platform.operatingSystem} messaging - Token');
developer.log(installationId, name: 'Firebase Installation ID');
dynamic requestData = await apiClient.post('/firebase/token', data: {
'device_id': udid,
'token_type': 'messaging', // 'messaging' or 'analytics
'token_value': token,
});
developer.log(requestData.toString(), name: 'Firebase Token');
//
locator.registerLazySingleton(() => firebaseApp);
locator.registerLazySingleton(() => firebaseAuth);
locator.registerLazySingleton(() => firebaseInAppMessaging);
return firebaseServers;
}
完整代码如上:
- 首先你要根据firebase入门文档进行操作.
- 在任意目录下创建
firebase_servers.dart
- 将上面完整代码粘贴到
firebase_servers.dart
- 在
main.dart
中引用import 'firebase_servers.dart';
- 在
main.dart
中使用它
import 'package:todoList_flutter/api/locator.dart';
import 'package:todoList_flutter/app.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todoList_flutter/simple_bloc_observer.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'dart:async';
import 'dart:developer' as developer;
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'firebase_servers.dart';
import 'android_system.dart';
import 'setup_request_permission.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
tz.initializeTimeZones();
Bloc.observer = const SimpleBlocObserver();
await setupRequestPermissions();
await setupLocator();
// 在这里使用-----
await setupFirebase();
runApp(const App());
// runZonedGuarded(() {}, (dynamic error, dynamic stack) {
// developer.log("Something went wrong!", error: error, stackTrace: stack);
// });
await setupInitAndroidSystem();
}
前台通知是使用flutter_local_notifications
这个插件实现的, 然后对这个插件也进行了封装.
代码如下:
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
class LocalNotificationsService {
int id = 0;
LocalNotificationsService._();
static final _instance = LocalNotificationsService._();
factory LocalNotificationsService() => _instance;
FlutterLocalNotificationsPlugin? _flutterLocalNotificationsPlugin;
Future selectNotification(String? payload) async {
// 处理通知点击事件
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
}
Future<FlutterLocalNotificationsPlugin> initialize() async {
// 初始化插件
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// 配置插件
// 配置Android初始化设置
const AndroidInitializationSettings androidInitializationSettings =
AndroidInitializationSettings('icon_notification');
// 配置iOS和macOS的初始化设置
const DarwinInitializationSettings darwinInitializationSettings =
DarwinInitializationSettings();
// 配置Linux的初始化设置
const LinuxInitializationSettings linuxInitializationSettings =
LinuxInitializationSettings(defaultActionName: 'default_action');
// 配置所有平台的初始化设置
const InitializationSettings initializationSettings =
InitializationSettings(
android: androidInitializationSettings,
iOS: darwinInitializationSettings,
macOS: darwinInitializationSettings,
linux: linuxInitializationSettings,
);
// 使用配置初始化插件
await _flutterLocalNotificationsPlugin!.initialize(
initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) {
// 处理通知点击事件
debugPrint('notification payload: ' + response.payload!);
},
);
return _flutterLocalNotificationsPlugin!;
}
Future<void> showNotification({
required String title,
required String body,
String? payload,
}) async {
id += 1;
// 显示通知
// 创建Android通知的详细设置
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('your channel id', 'your channel name',
channelDescription: 'your channel description', // 频道的描述。
importance: Importance.max, // 通知的重要性。
priority: Priority.high, // 通知的优先级。
ticker: 'ticker'); // 通知的提示文本。
// 创建通知渠道
// const AndroidNotificationChannel channel = AndroidNotificationChannel(
// 'my_notification_channel', // id
// 'My Notifications', // title
// // 'This channel is used for my notifications.', // description
// importance: Importance.max,
// );
// 创建通知的详细设置
const NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails); // 创建通知
// 显示通知
await _flutterLocalNotificationsPlugin!.show(
id, // 通知的 ID。
title, // 通知的标题。
body, // 通知的内容。
notificationDetails, // 通知的详细设置。
payload: payload, // 通知的数据。
);
}
Future<void> scheduleNotification({
required String title,
required String body,
required tz.TZDateTime scheduledDate,
}) async {
// 安排通知
// 定义本地通知的Android通知详细信息。
const AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails('your channel id', 'your channel name',
channelDescription: 'your channel description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
// 定义本地通知的详细信息。
const NotificationDetails notificationDetails =
NotificationDetails(android: androidNotificationDetails);
// 使用Flutter Local Notifications插件安排本地通知。
await _flutterLocalNotificationsPlugin!.zonedSchedule(
0, // 通知的ID。
title, // 通知的标题。
body, // 通知的正文。
scheduledDate, // 应安排通知的日期和时间。
notificationDetails, // 通知的详细信息。
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, // 安排模式。
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime, // 日期解释。
);
}
// 在这里添加更多不同类型的通知方法
// 例如:showImageNotification、showProgressNotification、showGroupNotification、addActionButtons等等
}
// // 安排通知
// final tz.TZDateTime scheduledDate =
// tz.TZDateTime.now(tz.local).add(Duration(seconds: 5));
// LocalNotificationsService().scheduleNotification(
// title: '安排通知标题',
// body: '安排通知内容',
// scheduledDate: scheduledDate,
// );
还有就是 想实现通知 你需要请求app的通知权限.
请求通知权限可以使用permission_handler
插件,也一样 对这个插件进行封装.
import 'package:permission_handler/permission_handler.dart';
Future requestPermissions() async {
// Request notification permission
PermissionStatus notificationStatus = await Permission.notification.request();
// Request other permissions
PermissionStatus cameraStatus = await Permission.camera.request();
PermissionStatus locationStatus = await Permission.location.request();
// Check the permission statuses
if (notificationStatus.isGranted) {
print('Notification permission granted');
} else {
print('Notification permission denied');
}
if (cameraStatus.isGranted) {
print('Camera permission granted');
} else {
print('Camera permission denied');
}
if (locationStatus.isGranted) {
print('Location permission granted');
} else {
print('Location permission denied');
}
}
Future setupRequestPermissions() async {
await requestPermissions();
}
这个封装就很基础了,没有使用很复杂的东西.