首页 > 解决方案 > 我想将所有联系人保存并检索到 Firebase Firestore,需要结构来保存和检索联系人

问题描述

我正在开发一个应用程序,有一个功能可以获取用户的所有联系人并将其上传到服务器。在这里,我使用 Firebase Firestore 作为我的后端。我可以获取所有联系人而不会重复。有人可以帮忙吗,我需要在哪个文档结构中保存用户的联系方式?请告诉我适当的格式,以免在 Firestore 中占用太多空间。

进而..

保存所有联系人后,我必须能够使用用户输入的号码获取联系人的姓名。这是我的要求。简而言之,我想知道如何为 Firestore 保存 2500 个联系人详细信息,以及如何借助用户在编辑文本中输入的联系人号码来读取单个联系人姓名。(注:听说不能一次性保存2500个用户的联系方式,应该用批量之类的)

在此处输入图像描述

我在下面的代码中尝试了这个,但它只保存了前 800 个联系人。

`private void doUploadContactstoCloud() {
        dialog.setCancelable(false);
        dialog.setMessage("Please wait we are configuring your request ...");
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();
        listContacts = new ContactPresenter(this).fetchAllContacts();
        int j = listContacts.size();

        Log.d("sizejhfg",j+"");

        double size = listContacts.size();
        double ind = 0;
        Map<String, Object> contact = new HashMap<>();
        // Get a new write batch
        WriteBatch batch = db.batch();
        for (Contact con : listContacts) {
            for (int i = 0; i < con.numbers.size(); i++) {
                String number = formatnum(con.numbers.get(i).number);
                if (number != null) {
                    if (!number.equals("0") && number.length() < 5) {

                        Map<String, Object> contactnumber = new HashMap<>();
                        contactnumber.put("name", con.name);
                        contactnumber.put("number", number);
                        contact.put(number,contactnumber);
                        DocumentReference item = db.collection(tonumber).document(number);
                        batch.set(item,contactnumber);
                        ind++;
                        if(ind==500){
                            doCommit(batch);
                            batch=db.batch();
                            ind=0;
                        }
                    }
                }
            }
            //dialog.setProgress((int) (ind / size) * 100);
        }
        if(ind>0){
            doCommit(batch);
        }
        prefManager.setisContactUpload(true);
        doDismissDialog();
    }` 
  1. 请告诉我应该如何在 Firestore(结构)中保存数据
  2. 请告诉我在号码的帮助下阅读单个联系人姓名

标签: javaandroidfirebasegoogle-cloud-firestoreandroid-contacts

解决方案


  1. 请告诉我应该如何在 Firestore(结构)中保存数据

如果您使用身份验证,您的应用程序用例可能的数据库架构可能是:

Firestore-root
   |
   --- users (collection)
        |
        --- uid (document)
             |
             --- // user properties
             |
             --- contacts (subcollection)
                   |
                   --- contactId (document)
                         |
                         --- phoneNumber: 123456789
                         |
                         --- // other contact properties

要获取用户拥有的所有联系人,只需在联系人引用上附加一个侦听器:

db.collection("users").document(uid).collection("contacts");
  1. 请告诉我在号码的帮助下阅读单个联系人姓名

要获取具有电话号码的单个联系人的详细信息,请使用以下查询:

db.collection("users").document(uid).collection("contacts").whereEqualTo("phoneNumber", 123456789);

根据官方文档中关于单个批次可以添加的最大文档数量

每个事务或每批写入最多可写入 500 个文档。

因此,您必须将联系人拆分为 500 个文档的一部分,以便能够将所有这些联系人添加到 Firestore。

编辑:

如果我假设一个用户的手机中有 4000 个联系人(只是手机号码和姓名*4000 = 8000 个来自单个用户的数据)。

这是不正确的,如果您只有 2 个属性(在一个联系人文档中),那么您将只有 4000 次写入操作,而不是8000 次,因为这两个属性都属于同一个文档。因此,您必须使用批处理写入或使用 POJO 类将它们一起编写。

如果用户数量变为 500 万,那么需要将大量数据存储在 Firestore 中。

这是正确的,但同时这意味着您将拥有一个非常成功的应用程序,并且您可以负担所有这些写入操作。500万相信我,这很多。

所以我想要一个最好的模式,它应该尽可能少地容纳空间

问题不在于空间,问题在于您执行的读写次数。Firestore 中的所有内容都与读写次数有关。

我期待一种非常有效的方式来保存数据。请帮忙

在我看来,上面的架构可以帮助您解决问题。

考虑到这仍然你的答案是最好的解决方案?

考虑到您对问题和评论的要求,是的。

是否可以忽略 uid、联系人 id 并且只能有这些参数

仅当您使用Firebase 实时数据库时,这是一个不同的产品。没有集合和文档,只有 JSON 数据库结构。


推荐阅读