【问题标题】:Firebase messaging - Notifications are not sent when app is Closed or sleep in FlutterFirebase 消息传递 - 当应用程序关闭或在 Flutter 中休眠时不会发送通知
【发布时间】:2021-06-07 06:26:22
【问题描述】:

我已经在 Flutter 中构建了我的应用,并且我已经实现了 LocalNotifications 和 FCM 消息传递。

这是我的代码:

 final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
  FlutterLocalNotificationsPlugin();


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

  }



  void registerNotification() {
    firebaseMessaging.requestNotificationPermissions();

    firebaseMessaging.configure(onMessage: (Map<String, dynamic> message) {
      print('onMessage: $message');
      return ;
    }, onResume: (Map<String, dynamic> message) {
      print('onResume: $message');
      return Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => NotificationsScreen()));
    },
        onLaunch: (Map<String, dynamic> message) {
      print('onLaunch: $message');
      return;
    });

    firebaseMessaging.getToken().then((token) {
      print('token: $token');
      FirebaseFirestore.instance
          .collection('Consultant')
          .doc(firebaseUser.uid)
          .update({'deviceToken': token});
    }).catchError((err) {
      //Fluttertoast.showToast(msg: err.message.toString());
    });
  }

  Future selectNotification(String payload) async {
    if (payload != null) {
      debugPrint('notification payload: $payload');
    }
    await Navigator.push(
      context,
      MaterialPageRoute<void>(builder: (context) => NotificationsScreen(payload: payload,)),
    );
  }

  void showNotification(message) async {
    var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
      Platform.isAndroid
          ? 'it.wytex.vibeland_pro_app'
          : 'it.wytex.vibeland_pro_app',
      'Vibeland Pro',
      'Vibeland Pro',
      playSound: true,
      enableVibration: true,
      importance: Importance.max,
      priority: Priority.high,
    );
    var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
    var platformChannelSpecifics = new NotificationDetails(
        android: androidPlatformChannelSpecifics, iOS: iOSPlatformChannelSpecifics);

    print(message);
    print(message['body'].toString());
    print(json.encode(message));

    await flutterLocalNotificationsPlugin.show(0, message['title'].toString(),
        message['body'].toString(), platformChannelSpecifics,
        payload: json.encode(message));

    await flutterLocalNotificationsPlugin.show(
      1, '???? Hai ricevuto un messaggio ???? ', 'Controlla subito le Tue notifiche ????????', platformChannelSpecifics,
      payload: 'item x',
    );
  }

  void configLocalNotification() {
    var initializationSettingsAndroid =
    new AndroidInitializationSettings('@mipmap/ic_launcher');
    var initializationSettingsIOS = new IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    );
    var initializationSettings = new InitializationSettings(
        android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
    flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

我在 firebase 中构建了一个函数来推送一些新集合作为通知。

const functions = require("firebase-functions");
const admin = require("firebase-admin");

admin.initializeApp(functions.config().firebase);

const fcm = admin.messaging();

exports.sendNotification = functions.firestore
    .document("Notifications/{id}")
    .onCreate((snapshot) => {
      const name = snapshot.get("name");
      const subject = snapshot.get("subject");
      const token = snapshot.get("token");

      const payload = {
        notification: {
          title: "" + name,
          body: "" + subject,
          sound: "default",
          click_action: "FLUTTER_NOTIFICATION_CLICK",
        },
      };

      return fcm.sendToDevice(token, payload);
    });

firebase_messaging: ^7.0.3flutter_local_notifications: ^4.0.1 的版本 目前由于与依赖项发生冲突,我没有升级。 通过这种方式,当应用程序打开时我会收到两个通知,我会正确收到本地通知,当应用程序处于前台和后台时,我会根据添加到我的 firestore 中的新集合获得 Firebasemessaging。 现在问题来了,当我关闭应用程序或几分钟后开始睡眠时应用程序...... 我收不到任何通知

要重新开始接收通知,我需要再次运行该应用并唤醒该应用。 这是我的应用程序的问题,因为我的应用程序通知非常重要,用户需要随时获取它们。

【问题讨论】:

    标签: firebase flutter google-cloud-firestore firebase-cloud-messaging


    【解决方案1】:

    正如您在FlutterFire documentation 上所做的那样,插件处理前台和后台通知的方式不同,因此您需要在您的应用中修复两件事。

    首先你需要准备你的云函数来发送后台通知以及前台,为此,你需要准备你的json不仅有一个notification还有一个data字段,如如下:

    const payload = {
        notification: {
          title: "" + name,
          body: "" + subject,
          sound: "default",
        },  
        data: {
            click_action: "FLUTTER_NOTIFICATION_CLICK"
        }
    };
    

    其次,您需要配置您的 firebaseMassaging 以接收后台消息,如下所示:

    firebaseMessaging.configure(
        onMessage: (Map<String, dynamic> message) {
            print('onMessage: $message');
            return ;
        }, 
        onResume: (Map<String, dynamic> message) {
            print('onResume: $message');
            return Navigator.push(
                context,
                MaterialPageRoute(
                builder: (context) => NotificationsScreen()));
        },
        onLaunch: (Map<String, dynamic> message) {
            print('onLaunch: $message');
            return;
        },
        onBackgroundMessage: myBackgroundMessageHandler
    );
    

    最后,您需要创建一个手动处理后台消息的处理程序,按照文档中的示例,您可以执行以下操作:

    Future<void> myBackgroundMessageHandler(RemoteMessage message) async {        
        print("Handling a background message: ${message}");
    }
    

    【讨论】:

    • 你认为有必要做广告吗:Future myBackgroundMessageHandler(RemoteMessage message) async { print("处理后台消息:${message}");等待 Firebase.initializeApp(); //这条线?? }
    • 如果应用程序已经初始化,我认为是这样。
    • 太好了,你救了我的应用程序和我的生命!
    • 很高兴能帮上忙 :)
    • 请阅读我所做的评论,因为我遇到了应用程序崩溃和错误:
    【解决方案2】:

    添加线:

    onBackgroundMessage: myBackgroundMessageHandler
    Future<void> myBackgroundMessageHandler(RemoteMessage message) async {        
        print("Handling a background message: ${message}");
    }
    
    

    我收到以下错误:

    Nexus, [10.03.21 16:59]
    [ File : app-release.apk ]
    
    Amore, [10.03.21 17:09]
    java.lang.RuntimeException: Unable to create service io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService: java.lang.RuntimeException: PluginRegistrantCallback is not set.
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:4023)
     at android.app.ActivityThread.access$1600(ActivityThread.java:224)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1903)
     at android.os.Handler.dispatchMessage(Handler.java:107)
     at android.os.Looper.loop(Looper.java:224)
     at android.app.ActivityThread.main(ActivityThread.java:7562)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
    Caused by: java.lang.RuntimeException: PluginRegistrantCallback is not set.
     at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.C(Unknown Source:70)
     at io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService.onCreate(Unknown Source:40)
     at android.app.ActivityThread.handleCreateService(ActivityThread.java:4011)
     ... 8 more
    

    【讨论】:

    • 尝试在这个community answer上做建议
    • This 也可以工作,导入 io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; 并将此代码添加到您的 onCreate - FlutterFirebaseMessagingService.setPluginRegistrant(this);
    猜你喜欢
    • 2021-02-23
    • 1970-01-01
    • 2019-12-30
    • 2021-02-19
    • 2021-06-25
    • 1970-01-01
    • 2020-12-31
    • 2017-01-13
    • 2020-11-17
    相关资源
    最近更新 更多