Flutter Firebase消息传递接收后台通知两次

beq87vna  于 2023-05-29  发布在  Flutter
关注(0)|答案(1)|浏览(235)

嗨,我正在创建一个接收后台和前台通知的futter应用程序,当在后台单击通知时,它应该导航到LoginPage.dart,当在前台接收时,它应该立即导航到LoginPage.dart,我不确定当应用程序终止时,此代码是否会收到通知
我的问题是如何解决这个问题,我的代码在后台收到两个通知,一个导航到LoginPage.dart,另一个没有
这是我的主 dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:sailerp4/LoginPage.dart';

Future<void> initializeLocalNotifications() async {
  final InitializationSettings initializationSettings = InitializationSettings(
    android: AndroidInitializationSettings('@mipmap/ic_launcher'),
    iOS: DarwinInitializationSettings(
      requestSoundPermission: true,
      requestBadgePermission: true,
      requestAlertPermission: true,
    ),
    macOS: null,
  );

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}

Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  final AndroidNotification? androidNotification = message.notification?.android;
  final DarwinNotificationDetails? iosNotificationDetails = message.notification?.apple != null
      ? DarwinNotificationDetails(
    sound: message.notification!.apple!.sound?.name,
    presentAlert: true,
    presentBadge: true,
    presentSound: true,
  )
      : null;
  final NotificationDetails platformChannelSpecifics = NotificationDetails(
    android: androidNotification != null
        ? AndroidNotificationDetails(
      'channelId',
      'channelName',
      channelDescription: 'channelDescription',
      importance: Importance.max,
      priority: Priority.high,
      playSound: true,
      enableVibration: true,
      enableLights: true,
      color: Colors.blue,
    )
        : null,
    iOS: iosNotificationDetails,
    macOS: null,
  );
  await FlutterLocalNotificationsPlugin().show(
    0,
    message.notification?.title ?? '',
    message.notification?.body ?? '',
    platformChannelSpecifics,
    payload: message.data['payload'],
  );
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  //Initialize local notifications
  await initializeLocalNotifications();
  Firebase.initializeApp();
  runApp(const MyApp());
  await Firebase.initializeApp();
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SAIL App',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.lightBlue,
      ),
      home: const MyHomePage(title: 'SAIL Emergency Response Notification'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  late final FirebaseMessaging messaging;

  Future<void> requestPermission() async {
    try {
      messaging = FirebaseMessaging.instance;
      final NotificationSettings settings = await messaging.requestPermission(
        alert: true,
        announcement: false,
        badge: true,
        carPlay: false,
        criticalAlert: false,
        provisional: false,
        sound: true,
      );
      final token = await messaging.getToken();
      print('this is my token: $token');
      if (settings.authorizationStatus == AuthorizationStatus.authorized) {
        print('user granted permission');
      }
      FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
        print('title: ${message.notification?.title} | Body: ${message.notification?.body}');
        await flutterLocalNotificationsPlugin.show(
          0,
          message.notification?.title ?? '',
          message.notification?.body ?? '',
          NotificationDetails(
            android: AndroidNotificationDetails(
              'channelId',
              'channelName',
              channelDescription: 'channelDescription',
              importance: Importance.max,
              priority: Priority.high,
              playSound: true,
              enableVibration: true,
              enableLights: true,
              color: Colors.lightBlueAccent,
            ),
          ),
        );
        firebaseMessagingBackgroundHandler(message);
      });
    } catch (e) {
      print('Error requesting permission: $e');
    }
  }

  @override
  void initState() {
    super.initState();
    requestPermission();
    Firebase.initializeApp().then((_) {
      requestPermission();
    });
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // Handle foreground messages
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => LoginPage()),
      );
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      // Handle background messages
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => LoginPage()),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const SizedBox(height: 32.0),
            Image.asset('assets/images/Sail_logo.png', height: 200.0, width: 250.0,
            ),
            const SizedBox(height: 16.0),
          ],
        ),
      ),
    );
  }
}

这是我的AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="SAIL ER"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />

        <meta-data  android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id" />

    </application>
</manifest>

我尝试了在initSate()中不添加此代码片段的代码

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // Handle foreground messages
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => LoginPage()),
      );
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      // Handle background messages
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => LoginPage()),
      );
    });

但是代码在收到后台通知时没有导航到LoginPage.dart,我在尝试调用Navigator.push()时遇到了问题,我遇到的问题是在BuildContext中,它一直给我未定义,不在同一个范围内

liwlm1x9

liwlm1x91#

变化

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // Handle foreground messages
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => LoginPage()),
      );
    });

FirebaseMessaging.instance.getInitialMessage().then(
    //push to scr
    },
  );

flutterLocalNotificationsPlugin.initialize(initializationSettings);

flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      onDidReceiveBackgroundNotificationResponse: _handlePushScreen,
      onDidReceiveNotificationResponse: _handlePushScreen,
    );

用于firebase通知

  • 当您收到通知时,FirebaseMessaging.onMessage.listen将运行。
  • FirebaseMessaging.instance.getInitialMessage()将在应用仍处于后台时点击通知时运行。
  • 当应用程序被终止时,当您点击通知时,FirebaseMessaging.onMessageOpenedApp.listen将运行。

用于本地通知

  • onDidReceiveBackgroundNotificationResponse将在您在应用处于后台或已终止时轻按通知时运行。
  • onDidReceiveNotificationResponse将在应用处于强制接地状态时轻按通知时运行。

相关问题