Lahari Areti
Lahari Areti

Reputation: 637

storing arrays into object datatype into firestore in android and iOS(swift)

Hi I have 2 arrays like phonenumber[1,2,3] amount[10,20,30] I need to store the data in a single document like field1: 1 field2: 10

The code I tried is

I took the object like **

public class Pojo {
    String invitee;
    Map<Integer,Integer>phoneAmount;
    public Pojo(String invitee, Map<Integer, Integer> phoneAmount)
    {
      this.invitee = invitee;
        this.phoneAmount=phoneAmount;
    }
}**

And in another class

 Map<int[], int[]> phoneAmount = new HashMap<>();
               phoneAmount.put(phonenumber,amount);


db.collection("Split").document("invitees").set(phoneAmount).addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    Log.d(TAG, "DocumentSnapshot successfully written!");
                }
            })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.w(TAG, "Error writing document", e);
                        }
                    });

It shows error like java.lang.RuntimeException: Could not serialize object. Maps with non-string keys are not supported at com.google.android.gms.internal.zzejw.zza(Unknown Source) at com.google.android.gms.internal.zzejw.zza(Unknown Source) at com.google.android.gms.internal.zzejw.zzbp(Unknown Source)

Upvotes: 1

Views: 2168

Answers (1)

Alex Mamo
Alex Mamo

Reputation: 138824

From the official documentation:

Although Cloud Firestore can store arrays, it does not support querying array members or updating single array elements.

This approach is one that I personally don't recommend it to be used. One of the many reasons also Firebase recommends against using arrays is that it makes the security rules impossible to write.

However, you can still model this kind of data by leveraging the other capabilities of Cloud Firestore.

Let's take an example. Suppose you have a database which look like this:

{
    title: "My Book",
    categories: [
        "science",
        "computer science",
        "technology"
    ]
}

You need to know that if you want to query for all books that are part of the "science" category, using this data structure, there is no way to perform this query.

To solve this, you can consider an alternative data structure, where each category is the key in a map and all values are true.

{
    title: "My Book",
    categories: {
        "science": true,
        "computer science": true,
        "technology": true
    }
}

And to query your database you can use this query:

db.collection("books")
    .whereEqualTo("categories.science", true)
    .get()
    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {/* ... */});

For your particular case, you can use a database structure that looks like this:

{
    title: "phonenumber",
    categories: {
        "12345": true,
        "67890": true,
        "43215": true
    }
}

To query, please use the following code:

db.collection("phonenumbers")
    .whereEqualTo("categories.12345", true)
    .get()
    .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {/* ... */});

Edit 13 Aug 2018:

According to the updated documentation regarding array membership, now it is possible to filter data based on array values using whereArrayContains() method. A simple example would be:

CollectionReference citiesRef = db.collection("cities");
citiesRef.whereArrayContains("regions", "west_coast");

This query returns every city document where the regions field is an array that contains west_coast. If the array has multiple instances of the value you query on, the document is included in the results only once.

Upvotes: 2

Related Questions