3

I am watching a video to create a simple app(just to practice concepts) where the user enters the title and their thoughts. This data will get sent to Firestore.

However, I was confused on the part where I send data through a HashMap:

Map<String, Object> data = new HashMap<>();
data.put(STRING_TITLE, title);
data.put(STRING_THOUGHTS, thoughts);

The title and thought are basically just the string values of the user's input for the title and thought.

String thoughts = edtThoughts.getText().toString().trim();
String title = edtTitle.getText().toString().trim();

After that, all I'm doing is just passing it into the journalRef: journalRef.set(data) where journalRef is just the DocumentReference of my database:

private FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference journalRef = db.collection("Journal").document("MyThoughts");

My question is: Why do we pass data as Map<String, Object> instead of Map<String, String>. Isn't the title and thoughts just the user's input as a String value?

Edit:

Also, when I go to Firestore, why does it show the thoughts and title as a String rather than an Object(which was declared in the HashMap)?

Hovers over data, shows string

Thanks!

Lukasz Blasiak
  • 642
  • 2
  • 10
  • 16
CodingChap
  • 1,088
  • 2
  • 10
  • 23

2 Answers2

3

In a Firestore document, field names are always precisely Strings, while the values are objects. It doesn't really matter if you want to add a String, a Boolean, a Number, or any kind of object that is a supported data type, all can be considered objects. The number one rule in Java is that everything is an object. So it doesn't matter what you add to the database, Firestore will always save the data according to its data type. To answer your question:

Why do we pass data as Map<String, Object> instead of Map<String, String>?

You need to pass the data according to the operation you need to perform. If you want to add data to the database using the set() method, then you can use Map<String, String> and this is because this method requires an argument of type Object. However, if you want to perform an update operation using the update() method, please note that you cannot use Map<String, String>, because the method requires a Map<String, Object>. Besides that, when you want to perform an update, you can pass different types of objects as values, and get the fields updated accordingly. So you can always update multiple fields at once.

Isn't the title and thoughts just the user's input as a String value?

Yes, it is. If you only want to add the title and thoughts using set(), then you can use Map<String, String>, otherwise, for an update operation, you need to use Map<String, Object>.

And to answer your edited question:

Also, when I go to Firestore, why does it show the thoughts and title as a String rather than an Object(which was declared in the HashMap)?

It will always display the values according to the values you have added. In the Firebase Console, there is no representation for an object other than the one for a map. Besides that, behind the scene, there is an instanceof verification for each object you add. So if if you pass a String, that Object will always be saved as a String and not in any other way.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
1

You can declare your above example as Map<String, String> because of the simple data you are putting in it. But a more advanced example might have you put a deeper structured object into Firestore, so use of Map<String, Object> is more appropriate. Firestore is a "document store database" where a document is a HashMap. The elements within that hash are name/value pairs, where the name is a string and the value can be: String, Boolean, Number, Timestamp, Array, (Hash)Map, Geolocation.

So declaring data as HashMap<String, Object> is more correct because of what could go into it.

Greg Fenton
  • 1,233
  • 9
  • 15