与朋友同步联系人-聊天应用Firebase

时间:2018-11-01 22:02:54

标签: javascript firebase google-cloud-firestore

我们正在使用一个包含实时聊天的应用程序,并且正在使用Firebase和React-Native。用户将使用其电话号码进行身份验证,因此我们正在使用电话号码身份验证服务。

当用户打开应用程序时,我们检索他们的联系人信息并将经过解析/过滤的电话号码发送到Cloud Function,此功能必须处理请求中发送的所有电话号码并将这些电话号码匹配的用户标记为朋友联系人电话号码之一。与Whatsapp相同的过程。

为此,我们尝试了两种方法:

  1. 函数接收到请求后,将遍历联系人的电话号码数组并查询Cloud Firestore数据库中的users集合。如果查询返回结果,该函数将检索该用户信息并将其添加到发出请求的用户的friends子集合中。

    /**
     * 
     * @param {string} userId - Firebase id of user that made the request
     * @param {Array<string>} contacts - Array of user's contacts phone numbers in E.164 format
     * @returns {Array<object>} Array containing registered contacts data 
     */
    exports.searchFriends = (userId, contacts) => {
      const registeredContacts = contacts.map(phoneNumber =>
        db.collection(constants.usersPublicCollection)
          .where('phoneNumber', '==', phoneNumber)
          .get()
          .then(snapshot => snapshot.docs.map((doc) => {
            if (doc.id !== userId) {
              return doc.data();
            }
            return null;
          })));
    
      return Promise.all(registeredContacts)
        .then(friends => friends.filter(friend => friend !== null));
        .then(friends => friends.reduce((prev, next) => [...prev, ...next], [])); // flatten array of arrays
    };
    
  2. 第二种方法是相同的过程,但是它使用方法getUserByPhonenumber()查询身份验证服务。

    /**
     * 
     * @param {string} userId - Firebase id of user that made the request
     * @param {Array<string>} contacts - Array of user's contacts phone numbers in E.164 format
     * @returns {Array<object>} Array containing registered contacts data 
     */        
    exports.searchFriends = (userId, contacts) => {
      const registeredContacts = contacts.map(phoneNumber =>
        admin.auth().getUserByPhoneNumber(phoneNumber)
          .then((user) => {
            if (user.uid !== userId) {
              return getUsersRef(user.uid).get();
            }
            return null;
          })
          .then((userProfile) => {
            if (!userProfile) {
              return null;
            }
            return userProfile.data();
          })
          .catch((err) => {
            if (err.code !== 'auth/user-not-found') {
              console.log(phoneNumber);
              console.error(err);
            }
            return null;
          }));
    
      return Promise.all(registeredContacts)
        .then(friends => friends.filter(friend => friend !== null));
    };
    

第一种方法行不通,因为当我们正在测试具有2k个联系人的用户时,我们发现此方法可能(并且仅一次)消耗了所有Cloud Firestore每天读取限制(50k)。
因此,我们尝试了第二种方法。此方法似乎有效,但是在调用该函数几次后,我们收到一条错误消息,表明我们已达到SocketConnectNonbillable的限制,我们尝试了大约2个小时后再次出现故障,但是在调用。但是,我们检查了配额页面,发现特定的配额很好,当时我们每天仅建立30个连接,每100秒仅建立0.3472个连接。

有人知道这个问题的解决方案吗?

如果有人在这些方法上发现问题或有更好的想法来解决联系人/朋友的需求(我们知道这些绝对不是最好的),欢迎提供任何反馈。

谢谢!

0 个答案:

没有答案
相关问题