dart 导航到另一个屏幕时,我点击Firebase推送通知无论是在前景或背景在Flutter

unhi4e5o  于 2023-06-27  发布在  Flutter
关注(0)|答案(4)|浏览(104)

我在我的Flutter应用程序中使用Firebase消息传递,当我点击通知时,我想导航到另一个屏幕,即使我的应用程序处于前台或后台,我使用了许多功能,它不会触发点击事件,我找不到任何可以解决我的问题。
当我点击应用程序在前台或后台时的通知时,什么也没有发生,因为它导航到同一页面。当我点击应用程序终止时的通知时,它会在启动屏幕上打开并进入主页,而不是我想要的屏幕。
我在我的Manifest中添加了这个intent-filter

<intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

我把它添加到Json对象中

"click_action": "FLUTTER_NOTIFICATION_CLICK",

下面是如何在main.dart中获取背景FCM

const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'high_importance', // id
    'High Importance Notifications', // title
    importance: Importance.high,
    playSound: true);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  SessionManager sessionManager = SessionManager();

  await Firebase.initializeApp();
  //final sound = 'sound.mp3';
  print('A bg message just showed up :  ${message.messageId}');

  final android = AndroidInitializationSettings('@mipmap/ic_launcher');
  final ios = IOSInitializationSettings(
    requestSoundPermission: false,
    requestBadgePermission: false,
    requestAlertPermission: false,);
  final settings = InitializationSettings(android: android,iOS: ios);
  flutterLocalNotificationsPlugin.initialize(settings,);
  if(message.data['title'].toString().toLowerCase()=="new request") {
    sessionManager.getBadge().then((badge) {
      if (badge != null) {
        int x = badge + 1;
        sessionManager.saveBadge(x);
        print("notification number is " + x.toString());
      }
      else {
        sessionManager.saveBadge(1);
      }
    });

  }

  flutterLocalNotificationsPlugin.show(
      message.data.hashCode,
      message.data['title'],
      message.data['body'],
      NotificationDetails(
        android: AndroidNotificationDetails(
          channel.id,
          channel.name,
          importance: Importance.high,
          priority: Priority.high,
         // sound: RawResourceAndroidNotificationSound(sound.split('.').first),
          playSound: true,
          icon: '@mipmap/ic_launcher',
        ),

      ));
  /*NotificationApi.showNotification(
      title: message.data['title'],
      body: message.data['body'],
      payload: "",
      id:  int.parse(channel.id));*/

}

Future<void>  main() async{
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
      AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);

  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,

  );
  

  runApp(MyApps());
  // configLoading();

}

class MyApps extends StatefulWidget {
  const MyApps({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return MyApp();
  }
}

class MyApp extends State<MyApps> {
  static  ValueNotifier<int> strikeNotifier = ValueNotifier(0);

  Color _primaryColor =  Color(0xff0d8b75);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
      builder: () => MaterialApp(
        debugShowCheckedModeBanner: false,
        home: SplashScreen(),
      ),
      designSize: const Size(1080, 2280),
    );
  }

  void showNotification(String title, String body) async {
    await _demoNotification(title, body);
  }

  Future<void> _demoNotification(String title, String body) async {
    var androidPlatformChannelSpecifics = AndroidNotificationDetails(
        'channel_I', 'channel name',
        showProgress: true,
        priority: Priority.high,
        playSound: true,
        ticker: 'test ticker');

    var iOSChannelSpecifics = IOSNotificationDetails();
    var platformChannelSpecifics = NotificationDetails(
        android: androidPlatformChannelSpecifics, iOS: iOSChannelSpecifics);
    await flutterLocalNotificationsPlugin
        .show(0, title, body, platformChannelSpecifics, payload: 'test');
  }

  @override
  void initState() {
    super.initState();

       FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage? message) {
  if (message != null) {
    Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));

  }
});

    getToken().then((value) {
      if(value!=null) {
        AppConstants.firebaseToken = value;
      }
    });

    FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    new FlutterLocalNotificationsPlugin();
    var initializationSettingsAndroid =  AndroidInitializationSettings('@mipmap/ic_launcher');
    var initializationSettingsIOS =  IOSInitializationSettings();
    var initializationSettings =  InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
    flutterLocalNotificationsPlugin.initialize(initializationSettings,
      );


    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      var data = message.data;
      //  AndroidNotification? android = message.notification?.android;/

      if (data != null ) {
        if(data['title'].toString().toLowerCase()=="new request") {
          SessionManager sessionManager = SessionManager(context);
          sessionManager.getBadge().then((badge) {
            if (badge != null) {
              setState(() {
                int x = badge + 1;
                strikeNotifier.value = x;
                sessionManager.saveBadge(x);
              });
            }
            else {
              strikeNotifier.value = 1;
              sessionManager.saveBadge(1);
            }
          });
        }
        print("entered");
        flutterLocalNotificationsPlugin.show(
            data.hashCode,
            data['title'],
            data['body'],
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                playSound: true,
                icon: '@mipmap/ic_launcher',
              ),
            ));

      }
    });
   FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
  Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));

});
   
  }

  Future<String?> getToken() async{
    String? token = await FirebaseMessaging.instance.getToken();
    print("token is "+token!);
    return token;

  }
}

单位:yaml

firebase_core: ^1.12.0
  firebase_messaging: ^11.2.6
dependency_overrides:
  firebase_messaging_platform_interface: 3.1.6

编辑:从多个解决方案中,我尝试了最常见的解决方案,我在initState中使用了onMessageOpenedApp,但它没有进入其中

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      Navigator.push(context, MaterialPageRoute(builder: (context)=>DoneAndPaiedPagess(0)));
    });
h6my8fg2

h6my8fg21#

在你的代码中,你使用的是flutter_local_notifications插件,当你从firebase messaging得到一个推送通知时,你正在创建本地通知。
由于通知不是由firebase消息传递创建的,因此您不会在getInitialMessageonMessageOpenedApp中获得tap回调。
为了在本地通知上获得自来水回调,可以在初始化flutter_local_notifications时传递回调函数

flutterLocalNotificationsPlugin.initialize(initializationSettings,
    onSelectNotification: onSelectNotification);

void selectNotification(String payload) async {
    if (payload != null) {
      debugPrint('notification payload: $payload');
// Here you can check notification payload and redirect user to the respective screen
      await Navigator.push(
         context,
         MaterialPageRoute<void>(builder: (context) => SecondScreen(payload)),
      );
    }
}

有关详细信息,您可以查看flutter_local_notifications文档

jdgnovmf

jdgnovmf2#

使用onMessageOpenedApp流监听在前台或后台打开通知的时间。当应用程序终止时,使用getInitialMessage获取挂起通知。

ecfsfe2w

ecfsfe2w3#

在initState中的home小部件上,检查getInitialMessage值:

// get the remote message when your app opened from push notification while in background state
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();

// check if it is exists
if (initialMessage != null) {
    // check the data property within RemoteMessage and do navigate based on it
}

请在www.example.com查看firebase flutter文档https://firebase.flutter.dev/docs/messaging/notifications/#handling-interaction。

z9zf31ra

z9zf31ra4#

我不确定这是否对现在有帮助。但是正如解释的那样,Firebase Messaging文档处理交互和github中的实际Firebase Messaging示例,您应该使用onMessageOpenedApp一个流,当应用程序从后台状态打开时发布RemoteMessage。和getInitialMessage如果应用程序从终止状态打开,将返回包含RemoteMessageFuture
您应该遵循GitHub示例中编写的代码,并以自己的方式实现它。希望这能帮上忙。

相关问题