【问题标题】:Flutter Firebase foreground push notification not showing but background is workingFlutter Firebase前台推送通知未显示但后台正在运行
【发布时间】:2022-01-03 11:22:30
【问题描述】:

我已经好几天没有尝试解决这个问题了。我已经为推送通知实现了 Firebase 消息传递,因此,我能够在应用处于后台时接收通知,但 在应用处于前台时无法接收强>。我尝试了所有可能的解决方案或在 stackoverflow/github 上,但到目前为止没有任何效果。以下是我尝试过的来源:

stackoverflow solution 1

stackoverflow solution 2

当前代码 =>

NotificationService.dart:

class NotificationService {
  static final FlutterLocalNotificationsPlugin
      _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

  static Future initialize() async {
    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    AndroidInitializationSettings androidInitializationSettings =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    InitializationSettings initializationSettings =
        InitializationSettings(android: androidInitializationSettings);

    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      // onSelectNotification: doSomething(),
    );
  }

  static Future showNotification(RemoteMessage message) async {
    AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
      "default_notification_channel_id",
      "channel",
      enableLights: true,
      enableVibration: true,
      priority: Priority.high,
      importance: Importance.max,
      largeIcon: DrawableResourceAndroidBitmap("ic_launcher"),
      styleInformation: MediaStyleInformation(
        htmlFormatContent: true,
        htmlFormatTitle: true,
      ),
      playSound: true,
    );

    await _flutterLocalNotificationsPlugin.show(
        message.data.hashCode,
        message.data['title'],
        message.data['body'],
        NotificationDetails(
          android: androidDetails,
        ));
  }
}

main.dart:

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print('Handling a background message ${message.messageId}');
  print('Notification Message: ${message.data}');
  NotificationService.showNotification(message);
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  runApp(
    MyApp(),
  );
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
    NotificationService.initialize();
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      NotificationService.showNotification(message);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(...)

还有一点要补充的是,当应用程序处于后台(我可以收到通知的情况)时,我得到前两个print 语句的输出,即message.messageId 和@ 987654329@:

I/flutter ( 3363): Handling a background message 0:1637822186109880%5dd28a92f9fd7ecd
I/flutter ( 3363): Notification Message: {body: Price is at Bull! Buy Now!, title: Hello Traders!}

但是当应用程序处于前台(我没有收到通知的情况)时,我得到以下输出:D/FLTFireMsgReceiver( 3363): broadcast received for message

如果有人可以帮助我,那真的很有帮助,已经调试了几天,找到了解决方案。 谢谢!

AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.trading_app">

  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  <uses-permission android:name="android.permission.INTERNET"/>

   <application
        android:label="TradingApp"
        android:icon="@mipmap/ic_launcher">

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_launcher" />

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

        <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
        <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
        </receiver>
        <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />

        <activity
            android:name=".MainActivity"
            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">

            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />

            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
            <!-- <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="high_importance_channel" /> -->
    </application>
</manifest>

【问题讨论】:

    标签: firebase flutter dart firebase-cloud-messaging


    【解决方案1】:

    我不知道它是否适合你,但这是我的代码,用于在应用程序在前台时显示通知。我将 messageHandler 放在 initState() 上。 LocalNotification 是一个自定义类,因此您可以创建一个相同的类,或者将任何内容放在 showNotificationonMessage

      Future<void> messageHandler() async {
      await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
        alert: true,
        badge: true,
        sound: true,
      );
    
      FirebaseMessaging.onMessage.listen((RemoteMessage event) {
        LocalNotification.showNotification(event);
      });
    
    }
    
      static Future<void> showNotification(RemoteMessage payload) async {
    
        var android = AndroidInitializationSettings('logo_rs');
        var initiallizationSettingsIOS = IOSInitializationSettings();
        var initialSetting = new InitializationSettings(android: android, iOS: initiallizationSettingsIOS);
        final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
        flutterLocalNotificationsPlugin.initialize(initialSetting);
    
    
    
        const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
            'default_notification_channel_id',
            'Notification',
            'All Notification is Here',
            importance: Importance.max,
            priority: Priority.high,
            ticker: 'ticker',
            icon: "logo_rs",
            playSound: true,
            sound: RawResourceAndroidNotificationSound("notification")
        );
        const iOSDetails = IOSNotificationDetails();
        const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidDetails, iOS: iOSDetails);
    
        await flutterLocalNotificationsPlugin.show(0, payload.notification!.title, payload.notification!.body, platformChannelSpecifics);
      }
    

    添加尝试将其放在您的 AndroidManifest 中

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

    String.xml(res/values 中的新文件)

    <?xml version='1.0' encoding='utf-8'?>
    <resources>
        <string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
    </resources>
    

    【讨论】:

    • 您好,感谢您的回答,但我认为根据您的回答,我没有遗漏任何内容!仍然没有显示,也没有错误...
    • 尝试将其放入您的 AndroidManifest &lt;meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id" /&gt; 并将您的频道 ID 更改为 'default_notification_channel_id'
    • 我按照你说的做了,但在调试时出现以下错误(构建失败):Element meta-data#com.google.firebase.messaging.default_notification_channel_id at AndroidManifest.xml:61:13-63:55 duplicated with element declared at AndroidManifest.xml:16:9-18:71。我认为这是因为重复的meta-data ?。我用AndroidManifest.xml编辑了这个问题。
    • 好的,那是因为有一个重复的meta-data(最后一个),我评论了它并且它构建成功但仍然看不到前台通知,后台通知正常工作.. .
    【解决方案2】:

    根据docs

    要在应用程序处于前台时收听消息,请收听 onMessage 流。

    因此,您应该在此处打印您的消息 ID 和数据。

    在您的 MyApp initState 中,

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      // print foreground message here.
      print('Handling a foreground message ${message.messageId}');
      print('Notification Message: ${message.data}');
    
      if (message.notification != null) {
        print('Message also contained a notification: ${message.notification}');
      }
    
      //.. rest of your code
      NotificationService.showNotification(message);
    });
    

    【讨论】:

    • 仍然,同样的输出,检查一些打印语句如何解决问题?
    • 您的问题是前台通知未显示。我上面的代码将确认您的设备已收到它。然后你知道错误来自showNotification()。当您说“相同的输出”时,您的代码是否打印“正在处理前台消息...”?
    • 不,它不打印Handling a foreground message,它只打印D/FLTFireMsgReceiver( 2809): broadcast received for message。好的,我明白你的意思了,那么 showNotification 可能有什么问题,因为它正在与 background 合作......
    猜你喜欢
    • 2023-04-11
    • 2019-06-24
    • 2021-07-27
    • 1970-01-01
    • 2020-02-14
    • 2019-08-05
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多