Search code examples
javaandroidfirebasegoogle-cloud-firestoreandroid-contacts

i want to save and retrive all contacts to Firebase Firestore, need structure to save and retrive contacts


I am developing an app, there's a functionality to get all the contacts of the user and upload it to server. Here I'm using Firebase Firestore as my backend. I can able to get all contacts without duplicates. Can someone please help, in which document structure I need to save the contact details of the user? Please tell me appropriate format so that it wont take much space in Firestore.

And then..

Once all the contacts are saved, I must be able to get the name of a contact using number what user is entering. This is my requirement. in short I would like to know how to save 2500 contact details for Firestore and how to read single contact name with help of contact number what user types in the edittext. (note : I heard like we cant save 2500 contact details of the user in one shot, something like batch should be used)

enter image description here

I tried this below code but it is saving only first 800 contacts only.

`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. Please tell how I should save data in Firestore (structure)
  2. please tell me to read single contact name with help of number

Solution

    1. Please tell how I should save data in Firestore (structure)

    If you are using authentication, a possible database schema for you app use-case might be:

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

    To get all contacts a user has, simply attach a listener on contacts reference:

    db.collection("users").document(uid).collection("contacts");
    
    1. please tell me to read single contact name with help of number

    To get the details of single contact having the phone number, please use the following query:

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

    According to the official documentation regarding the maximum number of documents that can be added in single batch:

    Each transaction or batch of writes can write to a maximum of 500 documents.

    So you have to split your contacts in parts of 500 documents in order to be able to add all those contacts to Firestore.

    Edit:

    if I assume one user is having 4000 contacts in his phone (just mobile number and name*4000 = 8000 data from a single user).

    That's incorrect, if you have only 2 properties (within a contact document), you'll only have 4000 write operations and not 8000 because both properties are apart of the same document. So you must write them together using a batch write or using a POJO class.

    if the number of users become 5 million then it will be huge data that needs to be stored on in the Firestore.

    That's correct but in the same time it means that you'll have a very successful application and you can afford all those write operations. 5 million believe me, it's much.

    so I want a schema which must the best which should accommodate less space as possible

    The problem is not about the space, the problem is about the number of reads and writes you perform. Evrything in Firestore is about the number of reads and writes.

    I am expecting a very efficient way to save data. please help

    In my optinion, the schema above can you help you solve the problem.

    considering this still your answer is the best solution?

    Considering your request from your question and comments, yes.

    is it possible to ignore uid, contact id and can just have only these parameters

    Only if you use Firebase realtime database, which is a different product. There are no collections and documents, just a JSON database structure.