【问题标题】:Clicking notification behavior only works when the app is in the background in flutter?单击通知行为仅在应用程序在后台运行时才有效?
【发布时间】:2021-11-02 21:48:21
【问题描述】:

我正在尝试使用 firebase 云功能向所有订阅自定义主题的用户推送通知,但在后台通知场景中,当单击通知时,它仅在应用程序处于后台时导航到所需的屏幕,但在终止应用程序和有一个通知它打开主屏幕不是通知主题

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';

const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'high_importance_channel', // id
    'High Importance Notifications', // title
    'This channel is used for important notifications.', // description
    importance: Importance.high,
    playSound: true);

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print('A bg message just showed up :  ${message.messageId}');
}

void subscribeToTopic() async {
  try {
    await FirebaseMessaging.instance.subscribeToTopic('notifications');
    print('subscribed to topic');
  } catch (e) {
    print('error is $e');
  }
}

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(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, this.title}) : super(key: key);

  final String? title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  
  @override
  void initState() {
    super.initState();
    subscribeToTopic();

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('onMessage data is ${message.data}');
      print('onMessage notification is ${message.notification}');

      RemoteNotification? notification = message.notification;
      AndroidNotification? android = message.notification?.android;
      if (notification != null && android != null) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                color: Colors.blue,
                playSound: true,
                icon: '@mipmap/ic_launcher',
              ),
            ));
      }
    });

 FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
    
      Navigator.pushNamed(context, '/productsScreen');
    
    });
    
  }

  void showNotification() async {
    setState(() {
      _counter++;
    });
    flutterLocalNotificationsPlugin.show(
        0,
        "Testing $_counter",
        "How you doin ?",
        NotificationDetails(
            android: AndroidNotificationDetails(
                channel.id, channel.name, channel.description,
                importance: Importance.high,
                color: Colors.blue,
                playSound: true,
                icon: '@mipmap/ic_launcher')));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title!),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: showNotification,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

【问题讨论】:

    标签: android flutter dart push-notification


    【解决方案1】:

    在您的应用从终止(已终止)状态打开后,您可以使用FirebaseMessaging.getInitialMessage()。见documentation

    FirebaseMessaging.onMessageOpenedApp 仅在应用程序处于后台状态但仍在运行时有效。所以在一天结束时,你的 main 看起来就像这样:

    RemoteMessage? initialMessage;
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      // We add this additional line to get the initial message
      initialMessage =  FirebaseMessaging.instance.getInitialMessage();
    
      FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
    
      await flutterLocalNotificationsPlugin
          .resolvePlatformSpecificImplementation<
              AndroidFlutterLocalNotificationsPlugin>()
          ?.createNotificationChannel(channel);
    
      await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
        alert: true,
        badge: true,
        sound: true,
      );
      runApp(MyApp());
    }
    

    如果initialMessage 不为空,您将知道用户点击了通知并且应用程序随即打开。在此之后,您可以根据需要处理 initialMessage 中的数据,最好在调用 runApp() 之后处理,因为您希望在用户打开应用程序后导航到不同的屏幕。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-22
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多