使用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
相关产品推荐
相关产品推荐

