【问题标题】:i want to save and retrive all contacts to Firebase Firestore, need structure to save and retrive contacts我想将所有联系人保存并检索到 Firebase Firestore,需要结构来保存和检索联系人
【发布时间】:2019-06-23 10:47:29
【问题描述】:

我正在开发一个应用程序,有一个功能可以获取用户的所有联系人并将其上传到服务器。在这里,我使用 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. 请告诉我借助号码读取单个联系人姓名

【问题讨论】:

    标签: java android firebase google-cloud-firestore android-contacts


    【解决方案1】:
    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);
    

    根据关于maximum number of documents that can be added in single batch的官方文档:

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

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

    编辑:

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

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

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

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

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

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

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

    在我的选择中,上面的架构可以帮助您解决问题。

    认为这仍然是您的最佳解决方案吗?

    考虑到您的问题和 cmets 的要求,是的。

    是否可以忽略uid,contact id,只能有这些参数

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

    【讨论】:

    • 我必须将大量数据保存到 Firestore,例如,如果我假设一个用户的手机中有 4000 个联系人(仅手机号码和姓名*4000 = 8000 个数据来自单个用户)。如果用户数量变为 500 万,那么需要将大量数据存储在 Firestore 中。所以我想要一个最好的模式,它应该尽可能少地容纳空间,我期待一种非常有效的方法来保存数据。请帮忙,除了保存和检索数据之外,我什么也不做。考虑到这仍然你的答案是最好的解决方案?
    • 是否可以忽略 uid、联系人 id 并且只能有这些参数(root user1mobilenumber (name-number) (name-number)…….. user2mobilenumber (name-number) (name- number)…….. user1mobilenumber (name-number) (name-number)…….. 这样吗?当我读什么的时候,我会传递 usermobile2 和 number,我需要 name。
    • 请查看我的更新答案,详细了解您在 cmets 中的所有问题。
    • 当然我明白了,但根据这个要求,什么是最好的使用..Realtime DB 或 Firestore?请更新。感谢您提供宝贵的信息并花时间澄清我的疑问。我想当我使用 realttime db 时,不可能用手机号码查询名称,因为这涉及到 2 级查询。
    • @AndroidManifester 这听起来像是另一个用例,所以请使用它自己的MCVE 发布另一个新问题,以便我和其他 Firebase 开发人员可以帮助您。
    猜你喜欢
    • 1970-01-01
    • 2017-12-01
    • 2010-11-11
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    相关资源
    最近更新 更多