我正在努力了解如何從推送通知類中導航以選擇顫動的通知。我需要訪問 BuildContext 或者想辦法告訴我的應用在沒有這個的情況下導航。
我的代碼如下所示:
主要.dart
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await PushNotificationService().setupInteractedMessage();
runApp(const MyApp());
}
Future awaitDeepLink() async {
StreamSubscription _sub;
try {
await getInitialLink();
_sub = uriLinkStream.listen((Uri uri) {
runApp(MyApp(uri: uri));
}, one rror: (err) {
});
} on PlatformException {
print("PlatformException");
} on Exception {
print('Exception thrown');
}
}
class MyApp extends StatelessWidget {
final Uri uri;
static final FirebaseAnalytics analytics = FirebaseAnalytics.instance;
const MyApp({Key key, this.uri}) : super(key: key);
@override
Widget build(BuildContext context) {
return OverlaySupport(
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus.unfocus();
}
},
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: buildThemeData(),
home: CheckAuth(uri: uri),
),
),
);
}
}
PushNotificationService.dart
class PushNotificationService {
Future<void> setupInteractedMessage() async {
RemoteMessage initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
String token = await FirebaseMessaging.instance.getToken();
var storage = const FlutterSecureStorage();
storage.write(key: "fcm_token", value: token);
if (initialMessage != null) {
print(initialMessage.data['type']);
}
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print("message opened app:" message.toString());
});
await enableIOSNotifications();
await registerNotificationListeners();
}
registerNotificationListeners() async {
AndroidNotificationChannel channel = androidNotificationChannel();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
var androidSettings =
const AndroidInitializationSettings('@mipmap/ic_launcher');
var iOSSettings = const IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
);
var initSettings = InitializationSettings(
android: androidSettings,
iOS: iOSSettings,
);
flutterLocalNotificationsPlugin.initialize(
initSettings,
onSelectNotification: onSelectNotification,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification notification = message.notification;
AndroidNotification android = message.notification.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: android.smallIcon,
playSound: true,
),
),
payload: json.encode(message.data),
);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
print("onMessageOpenedApp: $message");
if (message.data != null) {
print(message.data);
}
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
Future onSelectNotification(String payload) async {
Map data = json.decode(payload);
if (data['type'] == 'message') {
// NEED TO ACCESS CONTEXT HERE
// Navigator.push(
// navigatorKey.currentState.context,
// CupertinoPageRoute(
// builder: (navigatorKey.currentState.context) => MessagesScreen(
// conversationId: data['conversation_id'],
// userId: data['user_id'],
// name: data['name'],
// avatar: data['avatar'],
// projectName: data['project_name'],
// projectId: data['project_id'],
// plus: data['plus'],
// ),
// ),
// );
}
}
Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
print("onBackgroundMessage: $message");
}
enableIOSNotifications() async {
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
androidNotificationChannel() => const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
importance: Importance.max,
);
}
正如您在 onSelectNotification() 函式中看到的那樣,我正在嘗試導航但不知道如何導航。
我對飛鏢/顫振很陌生,所以任何指導都將不勝感激。
uj5u.com熱心網友回復:
//You can set a global key for your navigation:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// Pass it to MaterialApp:
new MaterialApp(
title: 'MyApp',
onGenerateRoute: generateRoute,
navigatorKey: navigatorKey,
);
// Push routes:
navigatorKey.currentState.pushNamed('/someRoute');
uj5u.com熱心網友回復:
我需要訪問 BuildContext
是的,您需要context導航。在顫振中,它的最佳實踐是在小部件中包含導航代碼。你有你的背景
來自Andrea Bizzotto的推文
規則:導航代碼屬于小部件
如果您嘗試將導航代碼放入業務邏輯中,您將遇到困難,因為您需要一個 BuildContext 來執行此操作。
解決方案:
- 發出新的小部件狀態
- 監聽小部件中的狀態并在那里執行導航
uj5u.com熱心網友回復:
創建一個流
StreamController<Map<String, dynamic>> streamController = StreamController<Map<String, dynamic>>();
然后在這里使用它
Future onSelectNotification(String payload) async {
Map data = json.decode(payload);
_streamController.add(data)
}
}
然后您可以在您的 MaterialApp 小部件下收聽主頁上的流
@override
void initState() {
streamController.stream.listen((event) {
if (data['type'] == 'message') {
Navigator.of(context).push(
CupertinoPageRoute(
builder: (context) => MessagesScreen(
conversationId: data['conversation_id'],
userId: data['user_id'],
name: data['name'],
avatar: data['avatar'],
projectName: data['project_name'],
projectId: data['project_id'],
plus: data['plus'],
),
),
);
}
});
super.initState();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/445203.html
