gpt4 book ai didi

performance - 如何加快此 Firestore 查询循环的性能?将电话联系人列表与 Firestore 数据库进行匹配

转载 作者:行者123 更新时间:2023-12-04 03:24:30 24 4
gpt4 key购买 nike

我正在将用户手机中的联系人电子邮件列表与我的 Firestore 数据库中的用户电子邮件列表进行比较,然后创建一个新的“contactsInApp”列表。

首先,我从 firestore 数据库中获取了整个用户集合。然后为每个用户创建一个 forEach 循环,检查我的电话联系人列表中的每个联系人是否匹配。如果匹配,它会创建一个新的“androidContactsInApp”列表。当有少量用户时它工作正常,但当我对 5,000 名用户进行测试时,它需要更长的时间 - 大约 30 秒。我认为 firestore 应该可以很好地扩展,所以想知道我的代码是否有问题。

这是我的代码:

fsDB.collection("users")
.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {
for (DocumentSnapshot document : documentSnapshots) {

String userEmail = document.get("email").toString();

for (UserInfoForRequest android_contact: arrayListAndroidContacts) {
String isEmailInDatabase = android_contact.getUserEmail();
String trimmedEmail = isEmailInDatabase.trim();
if (userEmail.equals(trimmedEmail)) {
String userID = document.getId();


UserInfoForRequest android_contact2 = new UserInfoForRequest();
android_contact2.setUserName(document.get("username").toString());
android_contact2.setUserEmail(userEmail);
android_contact2.setCurrentUID(currentUID);
android_contact2.setContactsUID(userID);
arrayListAndroidContactsInApp.add(android_contact2);

}


}

}
adapterWithApp.notifyDataSetChanged();
adapterNoApp.notifyDataSetChanged();
}
});

我也试过反转循环。这样做,我得到了我的电话联系人列表中的每个联系人,并且我对每个电话联系人执行了查询。这意味着我没有下载整个用户集合。这种方法要慢得多——慢得多。我认为那是因为我执行单独的、单独的查询。这是我的代码:

        for (final UserInfoForRequest android_contact: arrayListAndroidContacts) {

String contactsEmail = android_contact.getUserEmail();
String trimmedEmail = contactsEmail.trim();

fsDB.collection("users").whereEqualTo("email", trimmedEmail).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot documentSnapshots) {

if (documentSnapshots.isEmpty()) {
Log.d("FOUNDEMAIL", " document is empty ");

}
else {

List list = documentSnapshots.getDocuments();

DocumentSnapshot doc = (DocumentSnapshot) list.get(0);

UserInfoForRequest android_contact2 = new UserInfoForRequest();
android_contact2.setUserName(doc.get("username").toString());
android_contact2.setUserEmail(doc.get("email").toString());
android_contact2.setCurrentUID(currentUID);
android_contact2.setContactsUID(doc.getId());
arrayListAndroidContactsInApp.add(android_contact2);


adapterWithApp.notifyDataSetChanged();
adapterNoApp.notifyDataSetChanged();

}
}
})

编辑:好的,所以我做了一些测试。当我使用“快照监听器”而不是使用 .get 时,我能够节省 4 秒来检索文档快照,从 27.5 秒减少到 23.5 秒。我还发现循环本身只需要 4 秒——检索文档需要 19 秒。

然后我删除了 5,000 个用户并用 1,000 个用户进行了测试。 1,000 个用户的加载时间是 6.5 秒,循环本身也是。 1秒。这只是 firebase 需要解决以加快速度的问题吗?

最佳答案

我想出了一个大大加快搜索速度的方法。

代码没有问题。问题是它对客户端设备来说过于密集。

相反,我使用了 Cloud Functions,因此功能更强大的服务器本身可以处理循环。

  1. 获取设备上的联系人列表。
  2. 将联系人列表(电子邮件或电话号码)发送到 firestore 数据库中的特定文档。 IE..fsDB.doc("用户/UID/device_contacts);
  3. 创建一个在创建该文档时激活的云功能...exports.NewContactList = admin.firestore().doc('users/${UID}/device_contacts);
  4. 该函数读取文档,并查找其电子邮件或电话号码 == 文档中的电话或电子邮件的任何“用户”。
  5. 然后将这些用户放入一个新文档 - users/UID/suggestedFriends
  6. 然后客户端设备从创建的文档中读取建议好友列表。

此过程仍然需要时间,但仅限于您第一次创建建议列表时。它也会在后台发生,因此设备不会停滞。然后我还创建了一个函数,当新用户添加到数据库或用户电话中有新联系人时更新列表。

编辑

我写的函数...

exports.createdFriendListTest =     functions.firestore.document('users/{userID}/device_contacts/device_contacts').onCreate(event => {
console.log('test worked... function called after creating doc 1st time.');

const userID = event.params.userID;
const docWithContacts = event.data.data();
console.log(docWithContacts);

var promises = []; // to hold promises within the keyList.forEach loop.
const keyList = Object.keys(docWithContacts);
keyList.forEach(key => {

var promise = admin.firestore().collection('users').where('email', '==', key).get().then(querySnapshot =>{
console.log('querySnapshot obtained');
if (querySnapshot.empty) {
console.log('there is no user ', key, ' within database.');
return true;
} else {
console.log('user, ', key, ' exists in database');
querySnapshot.docs.forEach(docSnap => {

const userExistID = docSnap.id;
console.log('that user ID is ', userExistID);

const userData = docSnap.data();
console.log('user Data', userData);

const SuggestFriend = admin.firestore().doc(`users/${userID}/suggested_friends/${userExistID}`).set(userData);
return SuggestFriend.then(result => {
console.log('suggested friend added');
return true;
})
})
}
})
promises.push(promise);
})
return Promise.all(promises);
});

关于performance - 如何加快此 Firestore 查询循环的性能?将电话联系人列表与 Firestore 数据库进行匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47228993/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com