背景: 我有一个 flutter 应用程序,我的目标是使用 firebase 消息传递给订阅主题的用户处理推送通知消息。通知与使用处理程序中的SharedPreferences在本地保存的数据一起发送。这适用于 6 种情况中的 5 种。
此场景适用于 Android 和 IOS,同时满足以下条件:
在 IOS 上,当应用程序终止时,不会调用
onBackgroundMessage()
处理程序(即使推送通知通过并显示)的一种情况。但是,当您在第一个推送通知之后发送第二个推送通知时,处理程序确实会工作,因为第一个推送通知会唤醒应用程序。
我什至尝试在打开我放入
getInitialMessage()
功能中的应用程序后使用 main()
来获取消息。然而,该处理程序也没有被调用。因此,当应用程序终止时,我目前无法处理从 IOS 上的 firebase 推送通知获得的流程中的数据,即使用户确实收到了推送通知。
我已经做了什么:
flutter run --release
在发布模式下运行应用程序
main
和处理程序:
Future<void> firebaseMessagingForegroundHandler(
RemoteMessage message, BuildContext context) async {
// print("Handling a foreground message: ${message.notification?.title}");
var prefs = await SharedPreferences.getInstance();
var unreadMessages = prefs.getString('unreadMessages') ?? "";
var readMessages = prefs.getString('readMessages') ?? "";
int lastIndex = await getLastTabIndex();
if (lastIndex == 2) {
if (readMessages.isEmpty) {
prefs.setString('readMessages', jsonEncode([message.data]));
} else {
var listWithReadMessages = jsonDecode(readMessages);
listWithReadMessages.add(message.data);
prefs.setString('readMessages', jsonEncode(listWithReadMessages));
}
} else {
if (unreadMessages.isEmpty) {
prefs.setString('unreadMessages', jsonEncode([message.data]));
} else {
var listWithUnreadMessages = jsonDecode(unreadMessages);
listWithUnreadMessages.add(message.data);
prefs.setString('unreadMessages', jsonEncode(listWithUnreadMessages));
}
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Nieuwe melding van ${message.data['sender']}')));
}
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
debugPrint("Handling a background message: ${message.messageId}");
//To ensure the sharedpreferences plugin is loaded in.
DartPluginRegistrant.ensureInitialized();
var prefs = await SharedPreferences.getInstance();
prefs.reload();
var unreadMessages = prefs.getString('unreadMessages');
if (unreadMessages == null) {
prefs.setString('unreadMessages', jsonEncode([message.data]));
} else {
var listWithUnreadMessages = jsonDecode(unreadMessages);
listWithUnreadMessages.add(message.data);
prefs.setString('unreadMessages', jsonEncode(listWithUnreadMessages));
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
var messaging = FirebaseMessaging.instance;
await messaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
await messaging
.getInitialMessage()
.then((message) => firebaseMessagingBackgroundHandler);
runApp(const ProviderScope(child: MyApp()));
}
我从 FirebaseMessaging.onMessage.listen((message)
中的不同小部件运行
initState()
,而不是在我的
main()
中。
应用程序可以通过 FCM 接收消息有效负载之前必须满足一些先决条件:我强调。
申请必须至少打开过一次(以允许在 FCM 注册)。
- 在 iOS 上,如果用户从应用程序切换器上滑开应用程序,则必须手动重新打开应用程序,后台消息才能再次开始工作。
在 Android 上,如果用户从设备设置中强制退出应用程序,则必须手动重新打开应用程序,消息才能开始工作。- 在网络上,您必须使用网络推送证书请求令牌(使用 getToken())。
来源。
1- clean build cache files
flutter clean
flutter pub get
2- must to run from termnial as "realase" mode
flutter run --release