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

TypeScript Cloud Function:Firestore同校好友与非好友查询问题

问题分析与修正方案

原代码的核心问题

  1. 好友查询未过滤同校条件:原代码只查询了friends数组包含当前userId的用户,但没限制schoolRef,会返回其他学校的用户,不符合“同校好友”要求。
  2. 非好友查询逻辑错误:where('friends', 'not-in', '/users/' + userId)是完全错误的用法——not-in需要传入数组,且这里的逻辑应该是排除当前用户的好友列表,而非判断对方的好友列表里没有当前userId。
  3. 好友关系逻辑倒置:原代码查询的是“把当前用户加为好友的人”,但根据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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 22:14:54