TypeScript Cloud Function:Firestore同校好友与非好友查询问题
问题分析与修正方案
原代码的核心问题
- 好友查询未过滤同校条件:原代码只查询了
friends数组包含当前userId的用户,但没限制schoolRef,会返回其他学校的用户,不符合“同校好友”要求。 - 非好友查询逻辑错误:
where('friends', 'not-in', '/users/' + userId)是完全错误的用法——not-in需要传入数组,且这里的逻辑应该是排除当前用户的好友列表,而非判断对方的好友列表里没有当前userId。 - 好友关系逻辑倒置:原代码查询的是“把当前用户加为好友的人”,但根据User结构里的
friends字段定义(用户自己的好友ID数组),正确的好友应该是“当前用户friends数组里的用户”。
修正后的Cloud Function代码
export const onGetUserOptions = functions.https.onCall(async (data, context) => { const MAX_TOTAL_USER_OPTION = 4; const MAX_FRIENDS_OPTION = 2; const MAX_NON_FRIENDS_OPTION = MAX_TOTAL_USER_OPTION - MAX_FRIENDS_OPTION; const db = admin.firestore(); const usersCol = db.collection('users'); const userId = data.uid; const targetSchoolRef = data.schoolRef; try { // 1. 获取当前用户的文档,拿到自己的好友列表 const currentUserDoc = await usersCol.doc(userId).get(); if (!currentUserDoc.exists) { return { code: 404, status: 'error', message: '当前用户不存在' }; } const currentUserData = currentUserDoc.data(); const userFriends = currentUserData?.friends || []; // 好友ID数组 // 2. 查询同校的好友:从好友列表中筛选同校用户,最多2个 const friendsQuery = usersCol .where('uid', 'in', userFriends) .where('schoolRef', '==', targetSchoolRef) .limit(MAX_FRIENDS_OPTION); const friendsSnapshot = await friendsQuery.get(); const friends = friendsSnapshot.docs; // 3. 查询同校的非好友:排除自己和已有的好友,最多2个 // 注意:Firestore的not-in最多支持10个元素,若好友列表超过8个需要分批处理,这里假设好友数不多 const excludeIds = [...userFriends, userId]; const nonFriendsQuery = usersCol .where('uid', 'not-in', excludeIds) .where('schoolRef', '==', targetSchoolRef) .limit(MAX_NON_FRIENDS_OPTION); const nonFriendsSnapshot = await nonFriendsQuery.get(); const nonFriends = nonFriendsSnapshot.docs; // 合并结果 const options = [...friends, ...nonFriends]; return { code: 200, status: 'success', message: '用户选项获取成功', data: options.map(doc => ({ id: doc.id, ...doc.data() })) // 返回带ID的数据,方便前端使用 }; } catch (error) { console.error('获取用户选项失败:', error); return { code: 500, status: 'error', message: '获取用户选项失败' }; } });
关键说明
- 好友逻辑修正:改为从当前用户的
friends数组中筛选同校用户,符合字段定义的语义。 - 非好友过滤:通过
not-in排除当前用户自己和他的好友列表,确保返回的是同校陌生人。 - 异常处理:增加了用户不存在的判断和全局错误捕获,提升代码健壮性。
- 数据返回优化:把文档ID和数据合并返回,前端无需额外处理ID。
内容的提问来源于stack exchange,提问作者Rishabh
相关产品推荐
相关产品推荐

