Flutter地理位置与Firestore集成插件geo_firestore_flutter的使用

Flutter地理位置与Firestore集成插件geo_firestore_flutter的使用

简介

GeoFirestore 是一个用于在 Firestore 数据库中进行基于位置查询的 Flutter 实现。它允许开发者存储和检索地理位置数据,并根据地理区域创建查询。本文将介绍如何使用 geo_firestore_flutter 插件来实现这些功能。

GeoFirestore 对象

创建 GeoFirestore 实例

要创建一个新的 GeoFirestore 实例,您需要将其附加到 Firestore 集合引用:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:geo_firestore_flutter/geo_firestore_flutter.dart';

Firestore firestore = Firestore.instance;
GeoFirestore geoFirestore = GeoFirestore(firestore.collection('places'));

设置位置数据

要设置文档的位置,只需调用 setLocation 方法:

await geoFirestore.setLocation('tl0Lw0NUddQx5a8kXymO', GeoPoint(37.7853889, -122.4056973));

要删除某个位置并从数据库中删除该位置,可以调用:

await geoFirestore.removeLocation('tl0Lw0NUddQx5a8kXymO');

检索位置

如果文档不在 GeoFirestore 中,回调将返回 null。如果发生错误,回调将传递错误且位置为 null

final location = await geoFirestore.getLocation('tl0Lw0NUddQx5a8kXymO');
print('Location for this document is ${location.latitude}, ${location.longitude}');

地理查询

GeoFirestore 允许您使用 getAtLocation 方法查询地理区域内所有文档:

final queryLocation = GeoPoint(37.7853889, -122.4056973);

// 创建一个以 [37.7832, -122.4056] 为中心、半径为 0.6 公里的新查询
final List<DocumentSnapshot> documents = await geoFirestore.getAtLocation(queryLocation, 0.6);
documents.forEach((document) {
  print(document.data());
});

数据库结构

GeoFirestore 读写 Firestore 对象中的两个字段:“g”(geohash)和 “l”(纬度/经度):

{
  "g": "dr8vyzzwqd",
  "l": [
    43.2419, 
    -77.3881
  ]
}

此库主要灵感来源于 GeoFirestore-Android

示例 Demo

下面是一个完整的示例代码,展示了如何使用 geo_firestore_flutter 插件:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:geo_firestore_flutter/geo_firestore_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化 Firestore 和 GeoFirestore
  Firestore firestore = Firestore.instance;
  GeoFirestore geoFirestore = GeoFirestore(firestore.collection('places'));

  runApp(MyApp(geoFirestore: geoFirestore));
}

class MyApp extends StatelessWidget {
  final GeoFirestore geoFirestore;

  MyApp({required this.geoFirestore});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('GeoFirestore Example')),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 设置位置
              await geoFirestore.setLocation('placeId1', GeoPoint(37.7853889, -122.4056973));
              
              // 获取位置
              final location = await geoFirestore.getLocation('placeId1');
              if (location != null) {
                print('Location for placeId1 is ${location.latitude}, ${location.longitude}');
              } else {
                print('Location not found for placeId1');
              }

              // 查询附近地点
              final queryLocation = GeoPoint(37.7853889, -122.4056973);
              final List<DocumentSnapshot> nearbyPlaces = await geoFirestore.getAtLocation(queryLocation, 0.6);
              nearbyPlaces.forEach((doc) {
                print(doc.data());
              });
            },
            child: Text('Run GeoFirestore Demo'),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter地理位置与Firestore集成插件geo_firestore_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理位置与Firestore集成插件geo_firestore_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用 geo_firestore_flutter 插件在 Flutter 中集成地理位置与 Firestore 的代码示例。这个插件允许你根据地理位置查询 Firestore 数据库中的文档。

首先,确保你已经在 pubspec.yaml 文件中添加了必要的依赖项:

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^3.1.0  # 确保版本是最新的
  geo_firestore_flutter: ^0.4.0  # 确保版本是最新的,具体版本请查看pub.dev
  geolocator: ^9.0.0  # 用于获取地理位置
  google_maps_flutter: ^2.1.1  # 可选,用于显示地图

然后,运行 flutter pub get 来安装这些依赖项。

接下来,是一个完整的示例代码,展示了如何使用 geo_firestore_flutter 插件:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:geo_firestore_flutter/geo_firestore_flutter.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Geo Firestore Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GeoFirestoreDemo(),
    );
  }
}

class GeoFirestoreDemo extends StatefulWidget {
  @override
  _GeoFirestoreDemoState createState() => _GeoFirestoreDemoState();
}

class _GeoFirestoreDemoState extends State<GeoFirestoreDemo> {
  late GeoFirestore geoFirestore;
  late CollectionReference<Map<String, dynamic>> usersCollection;
  Position? currentPosition;

  @override
  void initState() {
    super.initState();
    usersCollection = FirebaseFirestore.instance.collection('users');
    geoFirestore = GeoFirestore(collectionRef: usersCollection);
    _getCurrentLocation();
  }

  Future<void> _getCurrentLocation() async {
    bool serviceEnabled;
    LocationPermission permission;

    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error('Location permissions are denied');
      }
    }

    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }

    currentPosition = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);

    setState(() {});
  }

  Future<void> _queryNearbyUsers() async {
    if (currentPosition == null) return;

    double radiusInKm = 10.0;
    Stream<List<DocumentSnapshot>> stream = geoFirestore
        .collection(collectionRef: usersCollection)
        .within(
          center: GeoPoint(currentPosition!.latitude!, currentPosition!.longitude!),
          radius: radiusInKm,
          field: 'position',
        );

    stream.listen((snapshot) {
      // 处理查询结果
      print('Nearby users: $snapshot');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Geo Firestore Flutter Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            currentPosition == null
                ? CircularProgressIndicator()
                : Text(
                    'Current Location: ${currentPosition!.latitude}, ${currentPosition!.longitude}',
                  ),
            ElevatedButton(
              onPressed: _queryNearbyUsers,
              child: Text('Query Nearby Users'),
            ),
          ],
        ),
      ),
    );
  }
}

说明:

  1. 依赖项:添加了 cloud_firestore, geo_firestore_flutter, geolocator, 和 google_maps_flutter 依赖项。
  2. 初始化:在 initState 方法中,初始化 GeoFirestoreCollectionReference,并调用 _getCurrentLocation 方法获取当前位置。
  3. 获取当前位置_getCurrentLocation 方法使用 geolocator 插件获取当前设备的地理位置。
  4. 查询附近用户_queryNearbyUsers 方法使用 geoFirestore 插件根据当前位置查询半径为 10 公里内的用户。
  5. UI:一个简单的 UI,显示当前位置和一个按钮,点击按钮将执行查询操作。

请确保你已经正确设置了 Firebase 项目,并且在 Firestore 数据库中有包含地理位置(使用 GeoPoint 类型)的文档。

注意:在实际应用中,你可能需要处理更多的错误情况和用户交互。此示例代码仅用于演示基本的集成和查询功能。

回到顶部