You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GeoFire查询Firestore时遇'geofire未定义'及部署错误

解决Firebase Functions中GeoFire地理查询的错误问题

问题根源

你使用的geofire包是为Firebase实时数据库设计的,并不适配Firestore,直接导入会导致函数加载失败。Firestore的地理查询需要使用专门的geofirestore包。

解决步骤

1. 替换依赖包

先卸载错误的geofire,安装适配Firestore的geofirestore:

npm uninstall geofire
npm install geofirestore

2. 修正导入与初始化代码

替换原来的geofire导入,改为初始化GeoFirestore实例:

const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();

// 导入并初始化GeoFirestore
const { GeoFirestore } = require('geofirestore');
const firestore = admin.firestore();
const geofirestore = new GeoFirestore(firestore);
// 获取users集合的GeoFirestore引用
const usersGeoRef = geofirestore.collection('users');

3. 修正地理查询逻辑

替换原有的地理查询方法,同时修复代码中的其他问题:

  • user_doc是DocumentReference,需先调用get()获取快照才能判断是否存在
  • 修正未定义的global_array变量
  • 改用async/await替代then回调链,避免异步逻辑混乱

修正后的完整函数代码:

const functions = require("firebase-functions");
const admin = require('firebase-admin');
admin.initializeApp();

const { GeoFirestore } = require('geofirestore');
const firestore = admin.firestore();
const geofirestore = new GeoFirestore(firestore);
const usersGeoRef = geofirestore.collection('users');

exports.sortQuery = functions.firestore.document('query_sorted/{user_uid}').onWrite(async (change, context) => {
    const user_uid = context.params.user_uid;
    const docAfter = change.after;
    const nearby_array = docAfter.get('nearby') || []; // 处理字段不存在的情况
    console.log('NEARBY ARRAY SIZE: ' + nearby_array.length);

    const usersRef = firestore.collection('users');
    const updateRef = firestore.collection('query_sorted').doc(user_uid);
    const userDocSnap = await usersRef.doc(user_uid).get(); // 获取用户文档快照

    let max_distance = '';
    let latitude = '';
    let longitude = '';
    let geohash = '';

    if(userDocSnap.exists){
        max_distance = userDocSnap.get('max_distance');
        latitude = userDocSnap.get('latitude');
        longitude = userDocSnap.get('longitude');
        geohash = userDocSnap.get('geohash');
    }

    if(nearby_array.length < 50) {
        console.log('NEARBY IF STATEMENT REACHED: ' + nearby_array.length);
        // 可替换为用户自身的经纬度作为查询中心
        const center = new admin.firestore.GeoPoint(26.3492374, 89.6293433);
        const radiusInKm = 50; // GeoFirestore默认以公里为单位

        // 执行地理查询
        const querySnapshot = await usersGeoRef.near({ center, radius: radiusInKm });
        
        const matchingDocs = [];
        // 收集所有需要添加的UID,批量更新减少Firestore调用
        const uidsToAdd = [];
        for (const doc of querySnapshot.docs) {
            const uid = doc.id; // 若文档ID不等于用户UID,改用doc.get('uid')
            const lat = doc.get('latitude');
            const lng = doc.get('longitude');
            
            // 精确校验距离
            const distanceInKm = geofirestore.distanceBetween(center, new admin.firestore.GeoPoint(lat, lng));
            if (distanceInKm <= radiusInKm) {
                uidsToAdd.push(`sorting_inside_successfull_${uid}`);
                matchingDocs.push(doc);
            }
        }

        // 批量更新
        if(uidsToAdd.length > 0) {
            await updateRef.update({
                nearby: admin.firestore.FieldValue.arrayUnion(...uidsToAdd)
            });
        }
        console.log('匹配到的文档数量:' + matchingDocs.length);
    }
    
    return null;
});

4. 额外注意事项

  • 确保users集合的文档包含geohash字段(GeoFirestore会自动维护该字段,若手动插入数据需保证格式正确)
  • 部署前在函数目录执行npm install,确保依赖安装完整
  • 批量更新比循环单条更新更节省资源,建议优先使用

内容的提问来源于stack exchange,提问作者Basudeb Barman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:20:48