#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,)
],
),
),
);
}
}
答案 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