#Flutter 后台消息无法在 Dart Firebase_messaging^9.1.0

时间:2021-04-01 00:38:55

标签: flutter firebase-cloud-messaging

#Flutter

你好

自从 firebase_messaging 获得 ^9.1.0 版本以来,我找不到答案,我该如何解决问题。

当我从邮递员发送邮件时,一切正常,我在被阻止的手机上收到通知,但控制台出现错误:

W/FirebaseMessaging(13437): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
W/FLTFireMsgService(13437): A background message could not be handled in Dart as no onBackgroundMessage handler has been registered.

当手机运行应用程序时,我从 Postman 发送另一篇文章,一切正常,我从控制台获取字符串:This is Walk Request ID:,但显示错误:

D/FLTFireMsgReceiver( 3689): broadcast received for message
W/FirebaseMessaging( 3689): Unable to log event: analytics library is missing
W/FirebaseMessaging( 3689): Unable to log event: analytics library is missing
E/flutter ( 3689): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: NoSuchMethodError: Class 'RemoteMessage' has no instance method '[]'.
E/flutter ( 3689): Receiver: Instance of 'RemoteMessage'
E/flutter ( 3689): Tried calling: []("data")
E/flutter ( 3689): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter ( 3689): #1      PushNotificationService.getWalkRequestId (package:app/Notifications/pushNotificationService.dart:65:30)
E/flutter ( 3689): #2      PushNotificationService.initialize.<anonymous closure> (package:app/Notifications/pushNotificationService.dart:20:31)
E/flutter ( 3689): #3      _rootRunUnary (dart:async/zone.dart:1362:47)
E/flutter ( 3689): #4      _CustomZone.runUnary (dart:async/zone.dart:1265:19)
E/flutter ( 3689): #5      _CustomZone.runUnaryGuarded (dart:async/zone.dart:1170:7)
E/flutter ( 3689): #6      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:341:11)
E/flutter ( 3689): #7      _DelayedData.perform (dart:async/stream_impl.dart:591:14)
E/flutter ( 3689): #8      _StreamImplEvents.handleNext (dart:async/stream_impl.dart:706:11)
E/flutter ( 3689): #9      _PendingEvents.schedule.<anonymous closure> (dart:async/stream_impl.dart:663:7)
E/flutter ( 3689): #10     _rootRun (dart:async/zone.dart:1346:47)
E/flutter ( 3689): #11     _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 3689): #12     _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 3689): #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 3689): #14     _rootRun (dart:async/zone.dart:1354:13)
E/flutter ( 3689): #15     _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 3689): #16     _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 3689): #17     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 3689): #18     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
E/flutter ( 3689): #19     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
E/flutter ( 3689): 
W/IInputConnectionWrapper( 3689): getExtractedText on inactive InputConnection
W/IInputConnectionWrapper( 3689): getTextBeforeCursor on inactive InputConnection

这是我的代码 pushNoti.dart,其中实现了 firebase 消息传递:

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:app/Models/walkDetails.dart';
import 'package:app/Notifications/notificationDialog.dart';
import 'package:app/configMaps.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import '../main.dart';
import 'dart:io' show Platform;

class PushNotificationService
{
  final FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;

  Future initialize(context) async
  {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      retrieveRideRequestInfo(getWalkRequestId(message), context);

      if (message.notification != null) {
        retrieveRideRequestInfo(getWalkRequestId(message), context);
      }
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('A new onMessageOpenedApp event was published!');
      Navigator.pushNamed(context, '/message',
      arguments: message);
    });
    Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async{
      await Firebase.initializeApp();
      print("Handling a background message: ${message.messageId}");
    }
    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
      await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
        badge: true,
      );
      runApp(MyApp());
    }
  }

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  AndroidNotificationDetails android = AndroidNotificationDetails('id', 'notiTitle', 'notiDesc', importance: Importance.max, priority: Priority.max);
  IOSNotificationDetails ios = IOSNotificationDetails();

  Future<String> getToken() async
  {
    String token = await firebaseMessaging.getToken();
    print("this is token ::");
    print(token);
    petsitterRef.child(currentfirebaseUser.uid).child("token").set(token);

    firebaseMessaging.subscribeToTopic("petsitters");
    firebaseMessaging.subscribeToTopic("users");
  }
  String getWalkRequestId(message)
  {
    String walkRequestID = "";
    if(Platform.isAndroid)
    {
      walkRequestID = message['data']['walk_request_id'];
    }
    else
    {
      walkRequestID = message['walk_request_id'];
    }

    return walkRequestID;
  }

  void retrieveRideRequestInfo(String walkRequestID, BuildContext context)
  {
    newRequestRef.child(walkRequestID).once().then((DataSnapshot dataSnapShot)
    {
      if(dataSnapShot.value != null)
      {
        double pickUpLocationLat = double.parse(dataSnapShot.value['pickup']['latitude'].toString());
        double pickUpLocationLng = double.parse(dataSnapShot.value['pickup']['longitude'].toString());
        String pickUpAddress = dataSnapShot.value['pickup_address'].toString();

        double dropOffLocationLat = double.parse(dataSnapShot.value['dropoff']['latitude'].toString());
        double dropOffLocationLng = double.parse(dataSnapShot.value['dropoff']['longitude'].toString());
        String dropOffAddress = dataSnapShot.value['dropoff_address'].toString();

        String paymentMethod = dataSnapShot.value['payment_method'].toString();

        WalkDetails walkDetails = WalkDetails();
        walkDetails.walk_reques_id = walkRequestID;
        walkDetails.pickup_address = pickUpAddress;
        walkDetails.dropoff_address = dropOffAddress;
        walkDetails.pickup = LatLng(pickUpLocationLat, pickUpLocationLng);
        walkDetails.dropoff = LatLng(dropOffLocationLat, dropOffLocationLng);
        walkDetails.payment_method = paymentMethod;

        print("Information :: ");
        print(walkDetails.pickup_address);
        print(walkDetails.dropoff_address);

        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (BuildContext context) => NotificationDialog(walkDetails: walkDetails,),
        );
      }
    });
  }
}

这是我初始化应用程序的主页选项卡:

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_geofire/flutter_geofire.dart';
import 'package:geolocator/geolocator.dart';
import 'app/AllScreens/registrationScreen.dart';
import 'package:app/Notifications/pushNotificationService.dart';
import 'package:app/configMaps.dart';
import 'package:app/main.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class HomeTabPage extends StatefulWidget
{
  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );

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

class _HomeTabPageState extends State<HomeTabPage> {
  Completer<GoogleMapController> _controllerGoogleMap = Completer();

  GoogleMapController newGoogleMapController;

  Position currentPosition;

  var geoLocator = Geolocator();

  String petsitterStatusText = "Offline Now - Go Online ";

  Color petsitterStatusTextColor = Colors.black;

  bool isPetsitterAvailable = false;

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

    getCurrentPetsitterInfo();
  }

  void locatedPosition() async
  {
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    currentPosition = position;

    LatLng latLatPosition = LatLng(position.latitude, position.longitude);

    CameraPosition cameraPosition = new CameraPosition(target: latLatPosition, zoom: 14.0);
    newGoogleMapController.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));

    //String address = await AssistantMethods.searchCoordinateAddress(position, context);
    //print("Twój adres / Your Address :: " + address);
  }

  void getCurrentPetsitterInfo() async
  {
    currentfirebaseUser = await FirebaseAuth.instance.currentUser;
    PushNotificationService pushNotificationService = PushNotificationService();

    pushNotificationService.initialize(context);
    pushNotificationService.getToken();
  }

  @override
  Widget build(BuildContext context)
  {
    return Stack(
      children: [


        GoogleMap(
          mapType: MapType.normal,
          myLocationButtonEnabled: true,
          initialCameraPosition: HomeTabPage._kGooglePlex,
          myLocationEnabled: true,
          onMapCreated: (GoogleMapController controller)
          {
            _controllerGoogleMap.complete(controller);
            newGoogleMapController = controller;

            locatedPosition();
          },
        ),

        //online offline petsitter
        Container(
          height: 140.0,
          width: double.infinity,
          color: Colors.black54,
        ),

        Positioned(
          top: 60.0,
          left: 0.0,
          right: 0.0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Padding(
                padding: EdgeInsets.symmetric(horizontal: 16.0),
                child: RaisedButton(
                  onPressed: ()
                  {
                    if(isPetsitterAvailable != true)
                    {
                      makePetsitterOnlineNow();
                      getLocationLiveUpdates();

                      setState(() {
                        petsitterStatusTextColor = Colors.green;
                        petsitterStatusText = "Online ";
                        isPetsitterAvailable = true;
                      });
                      
                      displayToastMessage("Jesteś Online / You are Online", context);
                    }
                    else
                      {
                        makePetsitterOfflineNow();
                        setState(() {
                          petsitterStatusTextColor = Colors.black;
                          petsitterStatusText = "Offline Now - Go Online ";
                          isPetsitterAvailable = false;
                        });
                        displayToastMessage("Jesteś Offline / You are Offline", context);
                      }
                  },
                  color: petsitterStatusTextColor,
                  child: Padding(
                    padding: EdgeInsets.all(17.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Text(petsitterStatusText, style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold, color: Colors.white),),
                        Icon(Icons.phone_android, color: Colors.white, size: 25.0,),
                      ],
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  void makePetsitterOnlineNow() async
  {
    Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
    currentPosition = position;

    Geofire.initialize("availablePetsitter");
    Geofire.setLocation(currentfirebaseUser.uid, currentPosition.latitude, currentPosition.longitude);

    walkRequestRef.onValue.listen((event) {

    });
  }

  void getLocationLiveUpdates()
  {
    homeTabPagestreamSubscription = Geolocator.getPositionStream().listen((Position position) {
      currentPosition = position;
      if(isPetsitterAvailable == true)
      {
        Geofire.setLocation(currentfirebaseUser.uid, position.latitude, position.longitude);
      }
      LatLng latLng = LatLng(position.latitude, position.longitude);
      newGoogleMapController.animateCamera(CameraUpdate.newLatLng(latLng));
    });
  }

  void makePetsitterOfflineNow()
  {
    Geofire.removeLocation(currentfirebaseUser.uid);
    walkRequestRef.onDisconnect();
    walkRequestRef.remove();
    walkRequestRef = null;
  }
}

这是我从邮递员发送时应该弹出的通知:(来自 pushNoti 的 onMessageOpenedApp)

import 'package:flutter/material.dart';
import 'package:app/Models/walkDetails.dart';

class NotificationDialog extends StatelessWidget
{

  final WalkDetails walkDetails;

  NotificationDialog({this.walkDetails});

  @override
  Widget build(BuildContext context)
  {
    return Dialog(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
      backgroundColor: Colors.transparent,
      elevation: 1.0,
      child: Container(
        margin: EdgeInsets.all(5.0),
        width: double.infinity,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(5.0),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(height: 30.0),
            Image.asset("images/walker_android.png", width: 120.0,),
            SizedBox(height: 18,),
            Text("New Walk Request", style: TextStyle(fontFamily: "Brand-Bold", fontSize: 18.0,),),
            SizedBox(height: 30,),
            Padding(
              padding: EdgeInsets.all(18.0),
              child: Column(
                children: [

                  Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Image.asset("images/pickicon.png", height: 16.0, width: 16.0,),
                      SizedBox(width: 20.0,),
                      Expanded(
                        child: Container(child: Text(walkDetails.pickup_address, style: TextStyle(fontSize: 18.0),)),
                      ),
                    ],
                  ),
                  SizedBox(height: 15.0),
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Image.asset("images/desticon.png", height: 16.0, width: 16.0,),
                      SizedBox(width: 20.0,),
                      Expanded(
                          child: Text(walkDetails.dropoff_address, style: TextStyle(fontSize: 18.0),)
                      ),
                    ],
                  ),
                ],
              ),
            ),

            SizedBox(height: 20.0),
            Divider(height: 2.0, color: Colors.black, thickness: 2.0,),
            SizedBox(height: 8.0),

            Padding(
              padding: EdgeInsets.all(20.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [


                  FlatButton(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(18),
                      side: BorderSide(color: Colors.red)),
                    color: Colors.white,
                    textColor: Colors.red,
                    padding: EdgeInsets.all(8.0),
                    onPressed: () {},
                    child: Text(
                      "Cancel".toUpperCase(),
                      style: TextStyle(
                        fontSize: 14.0,
                      ),
                    ),
                  ),

                  SizedBox(width: 25.0,),

                  RaisedButton(
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(18.0),
                        side: BorderSide(color: Colors.green)),
                      onPressed: () {},
                      color: Colors.green,
                      textColor: Colors.white,
                      child: Text("Accept".toUpperCase(),
                        style: TextStyle(fontSize: 14)),
                      ),

                ],
              ),
            ),

            SizedBox(height: 10,)
          ],
        ),
      ),
    );
  }
}

2 个答案:

答案 0 :(得分:0)

您应该在 main() 中使用“firebase app initialise”方法。您的代码中也存在格式问题,请将其更改为。

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

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

答案 1 :(得分:0)

render(){
   ......
   return(
   .....
   <View style={styles.numPadContainer}>
     {numberPads.map(numberPad => {
             let numPad = numberPad.id != 12 ?
                   <TouchableOpacity style={numberPad.style} key={numberPad.id}
                    onPress={() => this.onPressNumberPad(numberPad.value)}
                    >
                        <Text style={styles.numText} >{numberPad.value}</Text>
                   </TouchableOpacity> :
                   <TouchableOpacity style={numberPad.style} key={numberPad.id}
                    onPress={() => this.onPressDeletePad()}
                    >
                         <Image  source={require('../assets/images/clear-icon-50px.png')} />
                    </TouchableOpacity>
                    return (
                             numPad
                    )
       })}
    </View>
    ......
    )
}

使用此版本并遵循link