应用程序未在三种可能的应用程序状态下显示推送通知
App not showing Push Notifications on the three possible app states
我需要在我的 Flutter 应用中实现云消息传递。
目前,应用程序可以根据应用程序状态接收和显示推送通知,如下所示:
应用程序状态:已启动并在前台
Android:好的
iOS: 不行
应用程序状态:已启动并在后台
Android:好的
iOS: 好的
应用状态:已关闭
Android: 不行
iOS: 好的
我会把我当前的应用程序代码放在这里:
main.dart
///STREAM QUE CONTROLA LA RECEPCION DE MENSAJES CUANDO LA APP ESTA CERRADA O EN BACKGROUND
Future<void> backgroundHandler(RemoteMessage message) async{
//INICIALIZAMOS FIREBASE
await Firebase.initializeApp();
print(message.data.toString());
print(message.notification!.title);
}
Future<void> main() async {
//PERMITIR EL USO DE LIBRERIAS EXTERNAS QUE NECESITEN INTERACTUAR CON EL ARBOL DE WIDGETS
WidgetsFlutterBinding.ensureInitialized();
//INICIALIZACION DE EASYLOCALIZATION (TRADUCCION DE LA UI A EN, CA, ES)
await EasyLocalization.ensureInitialized();
//INICIALIZAMOS FIREBASE
await Firebase.initializeApp();
//INICIALIZAMOS EL STREAM PARA PODER RECIBIR MENSAJES CUANDO LA APP ESTE CERRADA O EN BACKGROUND
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
DarkThemeProvider themeChangeProvider = DarkThemeProvider();
runApp(EasyLocalization(
path: "idiomas",
fallbackLocale: Locale("es", "ES"),
saveLocale: true,
supportedLocales: [
Locale("en", "EN"),
Locale("es", "ES"),
Locale("ca", "CA")
],
child: MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) {
return themeChangeProvider;
}),
ChangeNotifierProvider(create: (_) => UsuarioProvider()),
ChangeNotifierProvider(create: (_) => EmpresaProvider()),
ChangeNotifierProvider(create: (context) => ApplicationBloc())
],
child: Consumer<DarkThemeProvider>(builder: (context, themeData, child) {
return MaterialApp(
theme: Styles.themeData(themeChangeProvider.darkTheme, context),
routes: {
"noticias": (_) => MyHomePage(currentIndex: 0,),
"avisos": (_) => MyHomePage(currentIndex: 1,),
"tareas": (_) => MyHomePage(currentIndex: 2,),
"perfil": (_) => MyHomePage(currentIndex: 3,),
},
home: MyApp());
}),
)));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? token = " ";
DarkThemeProvider themeChangeProvider = DarkThemeProvider();
void getCurrentAppTheme() async {
themeChangeProvider.darkTheme =
await themeChangeProvider.darkThemePreferences.getTheme();
}
Future<void>_init() async{
if(Platform.isIOS){
final settings = await FirebaseMessaging.instance.requestPermission();
if(settings.authorizationStatus == AuthorizationStatus.authorized){}
}
else
{}
}
@override
void initState() {
getCurrentAppTheme();
super.initState();
//COMPROBAMOS LA PLATAFORMA
if(Platform.isIOS){
//SOLICITAMOS PERMISOS A IOS PARA RECIBIR PUSH
_init();
}
//INICIALIZAMOS LOCAL NOTIFICATION SERVICE
LocalNotificationService.initialize(context);
//DEJAMOS PREPARADA LA APP PARA RECIBIR UNA PUSH Y ABRIRLA EN EK CASO DE QUE LA APP ESTE CERRADA
FirebaseMessaging.instance.getInitialMessage().then((message) {
if(message != null){
final routeFromMessage = message.data["route"];
Navigator.of(context).pushNamed(routeFromMessage);
}
});
///CON LA APP ACTIVA SE EJECUTA ESTA STREAM PARA OBTENER LOS DATOS DE LA PUSH
FirebaseMessaging.onMessage.listen((message) {
if(message.notification != null){
print(message.notification!.body);
print(message.notification!.title);
}
LocalNotificationService.display(message);
});
///CON LA APP ABIERTA PERO EN SEGUNDO PLANO Y EL USUARIO HACE CLICK
///SOBRE LA PUSH, LA APP SE REABRE ABRIENDO LA PANTALLA INDICADA EN ROUTES
FirebaseMessaging.onMessageOpenedApp.listen((message) {
final routeFromMessage = message.data["route"];
print("ruta recibida en la push ${routeFromMessage}");
Navigator.of(context).pushNamed(routeFromMessage);
});
}
@override
Widget build(BuildContext context) {
return
Consumer<DarkThemeProvider>(builder: (context, themeData, child) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
title: 'Evan.zero',
theme: Styles.themeData(themeChangeProvider.darkTheme, context),
home: MyHomePage(currentIndex: 0,),
);
});
}
}
local_notification_service.dart
class LocalNotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static void initialize(BuildContext context) {
final InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings("@drawable/ic_stat_zf"));
_notificationsPlugin.initialize(initializationSettings,onSelectNotification: (String? route) async{
if(route != null){
Navigator.of(context).pushNamed(route);
}
});
}
static void display(RemoteMessage message) async {
try {
final id = DateTime.now().millisecondsSinceEpoch ~/1000;
const NotificationDetails notificationDetails = const NotificationDetails(
android: AndroidNotificationDetails(
"evanzero",
"evanzero channel",
importance: Importance.max,
priority: Priority.high,
)
);
await _notificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,
payload: message.data["route"],
);
} on Exception catch (e) {
print(e);
}
}
}
我要求您检查代码并告诉我应该添加或删除什么以在两个平台和三种可能的状态下接收推送通知
Android 关闭应用程序并在前台和后台我的工作示例:
@override
void initState() {
super.initState();
var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = new IOSInitializationSettings();
var initializationSettings = new InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterNotificationPlugin = FlutterLocalNotificationsPlugin();
flutterNotificationPlugin.initialize(initializationSettings, onSelectNotification : onNotificationInForegroundPressed);
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
Beamer.of(context).beamToNamed(
'/myroot/${message.data["id"].toString()}/myroot2');
notifications.setNotificationOpened(message.data["id"]);
}
});
FirebaseMessaging.onMessage.listen(
(RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
notifications.setNotificationReceived(message.data['id'].toString());
var requestId = message.data['requestId'].toString();
var messageId = message.data['messageId'].toString();
FCMPayload fcmPayload = FCMPayload(id: '$id', messageId : '$messageId');
String fcmPayloadJsonString = fcmPayload.toJsonString();
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body.toString(),
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: 'launch_background',
),
),
payload: fcmPayloadJsonString
);
}
},
);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Beamer.of(context).beamToNamed(
'/myroot/${message.data["id"].toString()}/myroot2');
notifications.setNotificationOpened(message.data["messageId"]);
});
}
void Function()? onNotificationInForegroundPressed(String? payload) {
FCMPayload fcmpayload = FCMPayload.fromJsonString(payload!);
Beamer.of(context).beamToNamed(
'/myroot/${fcmpayload.requestId}/myroot');
notifications.setNotificationOpened(fcmpayload.messageId);
}
我需要在我的 Flutter 应用中实现云消息传递。
目前,应用程序可以根据应用程序状态接收和显示推送通知,如下所示:
应用程序状态:已启动并在前台
Android:好的
iOS: 不行
应用程序状态:已启动并在后台
Android:好的
iOS: 好的
应用状态:已关闭
Android: 不行
iOS: 好的
我会把我当前的应用程序代码放在这里:
main.dart
///STREAM QUE CONTROLA LA RECEPCION DE MENSAJES CUANDO LA APP ESTA CERRADA O EN BACKGROUND
Future<void> backgroundHandler(RemoteMessage message) async{
//INICIALIZAMOS FIREBASE
await Firebase.initializeApp();
print(message.data.toString());
print(message.notification!.title);
}
Future<void> main() async {
//PERMITIR EL USO DE LIBRERIAS EXTERNAS QUE NECESITEN INTERACTUAR CON EL ARBOL DE WIDGETS
WidgetsFlutterBinding.ensureInitialized();
//INICIALIZACION DE EASYLOCALIZATION (TRADUCCION DE LA UI A EN, CA, ES)
await EasyLocalization.ensureInitialized();
//INICIALIZAMOS FIREBASE
await Firebase.initializeApp();
//INICIALIZAMOS EL STREAM PARA PODER RECIBIR MENSAJES CUANDO LA APP ESTE CERRADA O EN BACKGROUND
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
DarkThemeProvider themeChangeProvider = DarkThemeProvider();
runApp(EasyLocalization(
path: "idiomas",
fallbackLocale: Locale("es", "ES"),
saveLocale: true,
supportedLocales: [
Locale("en", "EN"),
Locale("es", "ES"),
Locale("ca", "CA")
],
child: MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) {
return themeChangeProvider;
}),
ChangeNotifierProvider(create: (_) => UsuarioProvider()),
ChangeNotifierProvider(create: (_) => EmpresaProvider()),
ChangeNotifierProvider(create: (context) => ApplicationBloc())
],
child: Consumer<DarkThemeProvider>(builder: (context, themeData, child) {
return MaterialApp(
theme: Styles.themeData(themeChangeProvider.darkTheme, context),
routes: {
"noticias": (_) => MyHomePage(currentIndex: 0,),
"avisos": (_) => MyHomePage(currentIndex: 1,),
"tareas": (_) => MyHomePage(currentIndex: 2,),
"perfil": (_) => MyHomePage(currentIndex: 3,),
},
home: MyApp());
}),
)));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String? token = " ";
DarkThemeProvider themeChangeProvider = DarkThemeProvider();
void getCurrentAppTheme() async {
themeChangeProvider.darkTheme =
await themeChangeProvider.darkThemePreferences.getTheme();
}
Future<void>_init() async{
if(Platform.isIOS){
final settings = await FirebaseMessaging.instance.requestPermission();
if(settings.authorizationStatus == AuthorizationStatus.authorized){}
}
else
{}
}
@override
void initState() {
getCurrentAppTheme();
super.initState();
//COMPROBAMOS LA PLATAFORMA
if(Platform.isIOS){
//SOLICITAMOS PERMISOS A IOS PARA RECIBIR PUSH
_init();
}
//INICIALIZAMOS LOCAL NOTIFICATION SERVICE
LocalNotificationService.initialize(context);
//DEJAMOS PREPARADA LA APP PARA RECIBIR UNA PUSH Y ABRIRLA EN EK CASO DE QUE LA APP ESTE CERRADA
FirebaseMessaging.instance.getInitialMessage().then((message) {
if(message != null){
final routeFromMessage = message.data["route"];
Navigator.of(context).pushNamed(routeFromMessage);
}
});
///CON LA APP ACTIVA SE EJECUTA ESTA STREAM PARA OBTENER LOS DATOS DE LA PUSH
FirebaseMessaging.onMessage.listen((message) {
if(message.notification != null){
print(message.notification!.body);
print(message.notification!.title);
}
LocalNotificationService.display(message);
});
///CON LA APP ABIERTA PERO EN SEGUNDO PLANO Y EL USUARIO HACE CLICK
///SOBRE LA PUSH, LA APP SE REABRE ABRIENDO LA PANTALLA INDICADA EN ROUTES
FirebaseMessaging.onMessageOpenedApp.listen((message) {
final routeFromMessage = message.data["route"];
print("ruta recibida en la push ${routeFromMessage}");
Navigator.of(context).pushNamed(routeFromMessage);
});
}
@override
Widget build(BuildContext context) {
return
Consumer<DarkThemeProvider>(builder: (context, themeData, child) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
title: 'Evan.zero',
theme: Styles.themeData(themeChangeProvider.darkTheme, context),
home: MyHomePage(currentIndex: 0,),
);
});
}
}
local_notification_service.dart
class LocalNotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
static void initialize(BuildContext context) {
final InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings("@drawable/ic_stat_zf"));
_notificationsPlugin.initialize(initializationSettings,onSelectNotification: (String? route) async{
if(route != null){
Navigator.of(context).pushNamed(route);
}
});
}
static void display(RemoteMessage message) async {
try {
final id = DateTime.now().millisecondsSinceEpoch ~/1000;
const NotificationDetails notificationDetails = const NotificationDetails(
android: AndroidNotificationDetails(
"evanzero",
"evanzero channel",
importance: Importance.max,
priority: Priority.high,
)
);
await _notificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,
payload: message.data["route"],
);
} on Exception catch (e) {
print(e);
}
}
}
我要求您检查代码并告诉我应该添加或删除什么以在两个平台和三种可能的状态下接收推送通知
Android 关闭应用程序并在前台和后台我的工作示例:
@override
void initState() {
super.initState();
var initializationSettingsAndroid = new AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = new IOSInitializationSettings();
var initializationSettings = new InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterNotificationPlugin = FlutterLocalNotificationsPlugin();
flutterNotificationPlugin.initialize(initializationSettings, onSelectNotification : onNotificationInForegroundPressed);
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
Beamer.of(context).beamToNamed(
'/myroot/${message.data["id"].toString()}/myroot2');
notifications.setNotificationOpened(message.data["id"]);
}
});
FirebaseMessaging.onMessage.listen(
(RemoteMessage message) async {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
notifications.setNotificationReceived(message.data['id'].toString());
var requestId = message.data['requestId'].toString();
var messageId = message.data['messageId'].toString();
FCMPayload fcmPayload = FCMPayload(id: '$id', messageId : '$messageId');
String fcmPayloadJsonString = fcmPayload.toJsonString();
if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body.toString(),
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
icon: 'launch_background',
),
),
payload: fcmPayloadJsonString
);
}
},
);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Beamer.of(context).beamToNamed(
'/myroot/${message.data["id"].toString()}/myroot2');
notifications.setNotificationOpened(message.data["messageId"]);
});
}
void Function()? onNotificationInForegroundPressed(String? payload) {
FCMPayload fcmpayload = FCMPayload.fromJsonString(payload!);
Beamer.of(context).beamToNamed(
'/myroot/${fcmpayload.requestId}/myroot');
notifications.setNotificationOpened(fcmpayload.messageId);
}