Sharon
Sharon

Reputation: 3919

How do I store an object which contains an object to Firestore in Android?

I'm connecting to Cloud Firestore from my Android app. I need to save an object; That object contains a number of strings and ints, and also a couple of objects.

So, I have the following (simplified):

A MyColourList object which contains:

String name, description;
String[] colours;

A MyGrid object contains the following:

String name, description;
int numberOfLinks;
MyColourList colourList, colourListDefault;

I want to save a new MyGrid object to Firestore. The Firestore data structure is as follows:

grids > grid1ID > colourList
                     > name
                     > description
                     > colours
                          > 1
                            > White
                          > 2
                            > Black
                 > colourListDefault
                     > name
                     > description
                     > colours
                          > 1
                            > White
                          > 2
                            > Black
                 > description
                 > name
                 > numberOfLinks

To save this without the colourLists I just do this:

Map<String, Object> newGrid = new HashMap<>();
        newGrid.put("name", nameString);
        newGrid.put("description", descriptionString);
        newGrid.put("numberOfLink", num_links);
        databaseRef.collection("grids").add(newGrid);

which works fine.

However, when I try to add in the colourLists by doing this:

Map<String, Object> newGrid = new HashMap<>();
        newGrid.put("name", nameString);
        newGrid.put("description", descriptionString);
        newGrid.put("numberOfLink", num_links);
        newGrid.put("colourList", colourList);
        newGrid.put("colourListDefault", colourListDefault);
        databaseRef.collection("grids").add(newGrid);

I'm getting the following error and a crash: java.lang.IllegalArgumentException: Invalid data. Unsupported type: myapp.ColourList(found in field colourList)

I assume I need to map the colourLists in some way before I do this, but I can't find any examples of that. Can anyone advise me?

Upvotes: 1

Views: 6816

Answers (2)

Alex Mamo
Alex Mamo

Reputation: 138969

When using Cloud Firestore, you should use either POJO classes or either maps of primitive types but not mix them together. In your particular case, since you already have a MyGrid object, you should just write it directly to the database and then update it later, using the following lines of code:

MyGrid myGrid = // create your MyGrid object
yourReference.set(myGrid);
//Create your MyColourList objects and set the properties
MyColourList myColourList = new MyColourList();
MyColourList colourListDefault = new MyColourList();
myGrid.setColourList(colourList);
myGrid.setColourListDefault(colourListDefault);
yourReference.set(myGrid, SetOptions.merge());

It's true that this operation will have the cost of two write operations (one for adding the MyGrid object and second to update it) but this is the only way in which you can achieve this. The difficulty in allowing maps of POJOs is that it isn't clear how they should be extracted. So unfortunately, the Firestore SDK doesn't support this feature. It's only supported when you're updating the entire document using set() method. Please also see the official documentation for an example.

Upvotes: 1

Raj
Raj

Reputation: 3001

You can create a model or Pojo which contains all your variables, arrays and other objects. Then just put that to firestore database by using this:-

firestore.collection("grids").document(grid1ID).add(your_object).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
    @Override
    public void onSuccess(DocumentReference documentReference) {

    }
    })
    .addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(Exception e) {
            Toast.makeText(Activity_Name.this, "Error In Saving Details: " + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
     });

Upvotes: 1

Related Questions