在flutter中发送推送通知的条件应该放在哪里



我想构建一个应用程序,比如当我将带有纬度和经度信息的新数据保存到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);
  }
...

首先,您需要将fcm从通知消息更改为数据消息,以允许应用程序在后台处理消息。请在此处查看。

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(),
      title: snapshot.data().username,
      body: snapshot.data().description,
    },
  });
});

选中此处可在应用程序打开时显示推送通知。您的代码应该是这样的。

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (isValidDistance(message)) {
    print('onMessageListen');
    showNotification(message);
  }
});

Yo可以访问通过以下发送的数据

Map<String, dynamic> data = message.data;

然后后台处理程序将如下所示。

_messageHandler(RemoteMessaging message){
if (isValidDistance(message)) {
        print('onMessageListen');
        showNotification(message);
      }
}

或者创建一个Notification类,如下所示并使用。

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:geolocator/geolocator.dart';
import 'package:location/location.dart';
const AndroidNotificationChannel channel = AndroidNotificationChannel(
  'high_importance_channel', // id
  'High Importance Notifications', // title
  description: 'This channel is used for important notifications.',
  importance: Importance.max,
);
Future<LocationData> _getCurrentLocation() => Location().getLocation();
int getDistanceInMeters(currLat, currLng, lat, lng) {
  return Geolocator.distanceBetween(
    currLat,
    currLng,
    lat,
    lng,
  ).round();
}
Future<bool> isValidDistance(RemoteMessage messaging) async {
  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);
  var location = await _getCurrentLocation();
  int distance =
      getDistanceInMeters(location.latitude, location.longitude, lat, lng);
  var distanceInKm = (distance / 1000).round();
  print('Distance is: ${distanceInKm.toString()}');
  if (distance < 60000) {
    return true;
  }
  return false;
}
class NotificationServices {
  final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
    bool isValid = await isValidDistance(message);
    if (isValid) {
      print('onMessageListen');
      showNotification(message);
    }
  }
  backgroundNotification() {
    final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();
    final AndroidInitializationSettings _initialzationSettingsAndriod =
        AndroidInitializationSettings('@mipmap/ic_launcher');
    final IOSInitializationSettings _initialzationSettingsIOS =
        IOSInitializationSettings();
    final InitializationSettings _initializationSettings =
        InitializationSettings(
            android: _initialzationSettingsAndriod,
            iOS: _initialzationSettingsIOS);
    _flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);
    /// Update the iOS foreground notification presentation options to allow
    /// heads up notifications.
    FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );
    _flutterLocalNotificationsPlugin.initialize(_initializationSettings);
    FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage? message) async {
      if (message != null) await onClickNotificationHandler(message);
    });
    FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
      bool isValid = await isValidDistance(message);
      if (isValid) {
        print('onMessageListen');
        showNotification(message);
      }
    });
    FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
      await onClickNotificationHandler(message);
    });
  }
  onClickNotificationHandler(RemoteMessage message) async {
    Map<String, dynamic> data = message.data;
    print(data);
    //you can handle notificationand navigate to necessary  screen here.
  }
  showNotification(RemoteMessage message) {
    Map<String, dynamic> data = message.data;
    if (data["body"] != null) {
      flutterLocalNotificationsPlugin.show(
        data.hashCode,
        data["title"],
        data["body"],
        NotificationDetails(
          android: AndroidNotificationDetails(
            channel.id,
            channel.name,
            channelDescription: channel.description,
            icon: '@mipmap/ic_launcher',
          ),
          iOS: IOSNotificationDetails(
              presentAlert: true, presentBadge: true, presentSound: true),
        ),
      );
    }
  }
}

相关内容

  • 没有找到相关文章

最新更新