В настоящее время я борюсь с тем, чтобы уведомления запускались так, как я хочу, чтобы они появлялись во Флаттере.
Мое текущее решение состоит в том, чтобы иметь динамическую LandingPage, которая, в зависимости от FirebaseAuth, перенаправляется либо на страницу входа, либо на главный экран.
MaterialApp(
theme: ThemeData(
...
home: Scaffold(body: Builder(builder: (context) => LandingPage()))
),
Внутри LandingPage я вызову функцию в моем синглтоне для настройки уведомлений для меня. Как видите, я передаю контекст здесь. Это потому, что я хочу показать Snackbar из обратного вызова onMessage моих уведомлений.
class LandingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
FirebaseUser user = Provider.of<FirebaseUser>(context);
if (user != null) {
Singleton().setupMessaging(user.uid, context); //This is the line
return MainPage(userId: user.uid);
} else {
while(Navigator.canPop(context)){
Navigator.pop(context);
}
return LoginPage();
}
}
}
Этим я пытаюсь добиться, чтобы система обмена сообщениями работала, когда пользователь вошел в систему. Я устанавливаю обратные вызовы, только если текущий токен не определен.
Проблема, с которой я столкнулся сейчас, заключается в том, что указанный контекст не распространяется на все приложения, то есть, когда я перехожу к новому виджету, который имеет собственный контекст, снэк-панель больше не отображается. Теперь я не уверен, является ли это правильным местом для инициализации обмена сообщениями, так как отсутствует контекст для всего приложения.
setupMessaging(String uid) async{
if((await SharedPreferences.getInstance()).getBool('bNotifications') ?? true){
print("bNotifications disabled");
return;
}
_firebaseMessaging.getToken().then((token) {
if (_lastToken != token) {
if (_lastToken == null) {
if (Platform.isIOS) iOSPermission();
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('onMessage $message');
Scaffold.of(context).showSnackBar(...); //Here I need the context
},
onResume: (Map<String, dynamic> message) async {
print('onResume $message');
},
onLaunch: (Map<String, dynamic> message) async {
print('onLaunch $message');
},
);
}
_lastToken = token;
}
});
}
Я также рассмотрел возможность показа локальных уведомлений в обратном вызове onMessage, но локальные уведомления и обмен сообщениями через firebase не работают вместе на iOS.
Последний вариант, о котором я слышал, - это использование GlobalKey, который мне нужно будет пройти через все мои страницы. Этот подход также очень медленный, как я слышал.