【发布时间】:2021-12-31 19:57:22
【问题描述】:
我想构建一个应用程序,例如当我将带有纬度和经度信息的新数据保存到 Firebase 时,然后在我的应用程序中计算这些纬度和经度与用户当前位置之间的距离。如果距离小于 60 公里,则发送onBackgroundMessage 通知。我不会将用户的当前位置存储在 firebase 上。我使用函数_getCurrentLocation 获取用户的当前位置。
问题是我不知道在哪里以及如何放置isValidDistance 来检查距离是否低于 60 公里。
目前我的应用会发送通知,但不是按距离发送通知。
index.js
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.myFunction = functions.firestore
.document("animal/{message}")
.onCreate((snapshot, context) => {
return admin.messaging().sendToTopic("animal", {
data: {
latitude: snapshot.data()["latitude"].toString(),
longitude: snapshot.data()["longitude"].toString(),
},
notification: {
title: snapshot.data().username,
body: snapshot.data().description,
clickAction: "FLUTTER_NOTIFICATION_CLICK",
},
});
});
main.dart
Future<void> _messageHandler(RemoteMessage message) async {
print('background message ${message.data}');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double? currentLatitude;
double? currentLongitude;
Future<void> _getCurrentLocation() async {
final locData = await Location().getLocation();
setState(() {
currentLatitude = locData.latitude;
currentLongitude = locData.longitude;
});
}
int getDistanceInMeters(currLat, currLng, lat, lng) {
return Geolocator.distanceBetween(
currLat,
currLng,
lat,
lng,
).round();
}
bool isValidDistance(RemoteMessage messaging) {
Map<String, dynamic> data = messaging.data;
var _list = data.values.toList();
var lat = double.parse(_list[0]);
var lng = double.parse(_list[1]);
print(_list);
int distance =
getDistanceInMeters(currentLatitude, currentLongitude, lat, lng);
var distanceInKm = (distance / 1000).round();
print('Distance is: ${distanceInKm.toString()}');
if (distance < 60000) {
return true;
}
return false;
}
@override
void initState() {
super.initState();
_getCurrentLocation();
final messaging = FirebaseMessaging.instance;
messaging.subscribeToTopic('animal');
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (isValidDistance(message)) {
print('onMessageListen');
}
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
if (isValidDistance(message)) {
print('onMessageOpened');
}
});
FirebaseMessaging.onBackgroundMessage(_messageHandler);
}
...
【问题讨论】:
-
目前您收到通知时会记录哪些打印语句?
-
我不确定我是否理解它。
if (isValidDistance(message)) { print('onMessageOpened'); }语句在距离有效时打印日志。我写这个语句只是检查我的代码并试图理解发送推送通知。目前我收到所有通知,但我不知道该怎么做 -
当前打开应用且位置无效时是否收到通知?因为您在使用 onmessage 打开应用程序时处理了通知。但是,对于应用程序关闭时的通知,您需要在后台创建一个特定于平台的通道来处理。查看medium.com/flutter/…。
-
没有。打开应用程序时,我没有收到任何通知。它只是在距离有效时打印日志“onMessageListen”。所以当应用程序关闭时,我无法通过颤动的距离处理推送通知?如果我在 android 和 ios 文件夹中执行此操作,唯一的处理方法是?
-
是的,这就是它的工作原理。同样通过您的代码,您正在发送一条通知消息,因此当应用程序处于后台时,firebase 会自动显示它。选中此项以获取数据消息和通知消息 firebase.google.com/docs/cloud-messaging/… 之间的区别。您可以使用 FirebaseMessaging.onBackgroundMessage() 在后台处理数据消息,但它必须是顶级函数。
标签: firebase flutter dart google-cloud-functions