我实现了onBackgroundMessage抖动,该抖动在设备收到Firebase Cloud Messaging数据消息时触发;我应该打开一个弹出窗口,但是在此事件处理程序中,我没有context
对象。什么是实现此目标的正确方法?
答案 0 :(得分:1)
如果要在应用程序中显示弹出窗口,则不需要onBackgroundMessage
-仅用于在后台收到消息时处理数据。收到消息后,无法启动应用程序。
但是,如果用户点击通知,该应用将启动,并且将调用onResume或onLaunch回调。
您可以通知相关屏幕在发生这种情况时显示弹出窗口。
这是一个简单的实现:
在firebase_notification_receiver.dart
中:
import 'dart:async';
import 'package:firebase_messaging/firebase_messaging.dart';
class NotificationEvent {
final Map<String, dynamic> content;
/// whether the notification was delivered while the app was in the foreground
final bool inApp;
NotificationEvent({this.content, this.inApp = false});
}
class FirebaseNotificationReceiver extends NotificationReceiver {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
StreamController<NotificationEvent> _controller = StreamController<NotificationEvent>.broadcast();
StreamSubscription _streamSubscription;
Function(NotificationEvent) _listener;
init{
// add the rest of the code to initialise firebase here
_firebaseMessaging.configure(
/// Fires when App was in foreground when receiving the notification
onMessage: (Map<String, dynamic> message) async {
print("onMessage: $message");
_controller.sink.add(NotificationEvent(content: message, inApp: true));
},
/// Fires when App was in background when receiving the notification and user has tapped on it
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
_controller.sink.add(NotificationEvent(content: message));
}
/// Fires when App was closed when receiving the notification and user has tapped on it
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
_controller.sink.add(NotificationEvent(content: message));
},
);
_streamSubscription =
_controller.stream.listen(_onStreamEvent, onError: (e) {
print("Notification Stream error $e");
});
}
setListener(Function(NotificationEvent) onData) {
this._listener = onData;
}
}
在main.dart
中:
// imports go here
void main(){
final notificationReceiver = NotificationReceiver.firebase();
runApp(
MultiProvider(
providers: [
Provider<NotificationReceiver>(
builder: (_) => notificationReceiver),
// more providers go here
],
child: App(), // Your custom app class
),
);
}
在notification_listenable.dart
中:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class NotificationListenable extends StatefulWidget {
final Widget child;
final Function(NotificationEvent) onData;
const NotificationListenable({@required this.child, this.onData});
@override
_NotificationListenableState createState() => _NotificationListenableState();
}
class _NotificationListenableState extends State<NotificationListenable> {
@override
Widget build(BuildContext context) {
Provider.of<NotificationReceiver>(context).setListener(widget.onData);
return widget.child;
}
}
在my_screen.dart中:
/// add your imports here
class MyScreen extends StatefulWidget {
@override
HomePageState createState() => HomePageState();
}
class MyScreenState extends State<MyScreen> {
final _scaffoldKey = GlobalKey<ScaffoldState>();
void _onNotification(NotificationEvent n) {
(_scaffoldKey.currentState)?.showSnackBar(
SnackBar(
duration: Duration(seconds: 2),
content: Text("I am a pop up"),
),
),
}
@override
Widget build(BuildContext context) {
return NotificationListenable(
child: YourCustomScreenContent(),
onData: _onNotification,
);
}
答案 1 :(得分:0)
我用静态方法创建了一个类:
class FirebaseMessagingHandler {
final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
final _bloc = AppModule.to.getBloc<FirebaseMessagingHandlerBloc>();
void setListeners() {
if (Platform.isIOS) _iOSPermission();
getToken();
refreshToken();
}
void getToken() {
firebaseMessaging.getToken().then((token) {
_bloc.saveToken(token);
print('DeviceToken = $token');
});
}
void _iOSPermission() {
firebaseMessaging.configure();
firebaseMessaging.requestNotificationPermissions(IosNotificationSettings(sound: true, badge: true, alert: true));
firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
});
}
void refreshToken() {
firebaseMessaging.onTokenRefresh.listen((token) {
_bloc.refreshToken(token);
});
}
void showDialog(BuildContext context, Map<String, dynamic> message) {
// data
}
void showErrorDialog(BuildContext context, dynamic error) {
// data
}
void redirectToPage(BuildContext context, Map<String, dynamic> message) {
// data
}
}
在我的主页(打开我的应用程序时始终会调用该页面)中,我调用了configure:
class _HomePageState extends State<HomePage> {
final _fcm = FirebaseMessagingHandler();
@override
void initState() {
super.initState();
firebaseCloudMessagingListeners();
}
void firebaseCloudMessagingListeners() {
_fcm.firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
try {
_fcm.showDialog(context, message);
} catch (e) {
_fcm.showErrorDialog(context, e);
}
},
onLaunch: (Map<String, dynamic> message) async {
try {
_fcm.redirectToPage(context, message);
} catch (e) {
_fcm.showErrorDialog(context, e);
}
},
onResume: (Map<String, dynamic> message) async {
try {
_fcm.redirectToPage(context, message);
} catch (e) {
_fcm.showErrorDialog(context, e);
}
},
);
}
}