Wednesday, June 9, 2021

Firebase database model - tips for querying

0_Unsorted_

Storage, documents and collections

Let's distinguish all the terms in three groups: storage, documents and collections.
Storage is the mostly memory consuming part of database. Any data submitted by the user is stored in the storage. Whether it is text, picture or geo location. In the code, we don't call the storage directly. Instead, we use documents to reference it.
Documents present hash maps to reference the storage. Hash map is needed because the document has multiple fields and each field should have a reference to the value.
Collections are merely tags to combine documents into groups. So if we would not have collections initially, we could easily create them. For that, just create a new "collection" field in the document and place there some collection name. So all the documents with that value will be combined into the same collection group. 
That's why we cannot create subcollection inside of the collection. We can create subcollection only inside of the document. Because the document can easily reference anything in its hash, whether it is value in storage, name of the collection etc. Collection cannot reference anything because the collection per se is merely the name of the tag which is referenced by the document.
For the same reason, multiple documents in the same collection (though it would be proper to say "of the same collection") can contain different fields with different types of values. Collection does not restrict the document. Instead, it just places a marker on the document, it marks the document with some kind of tag and nothing else.
Say we have multiple dogs in the yard. Some of them are white and some are not. Our task is to call all the white dogs and gather them for a walk to the park. In a regular database, dogs don't want to listen to our commands. So we need to build up a crate called "table of white dogs" and lock all the white dogs into that crate. So we don't need to spend time for searching for dogs of particular color.
In NoSQL database like Firebase, dogs are smarter and they can listen to our commands. Every white dog has a "white" tag on its collar. Instead of being locked and crowded in the crate, they can freely walk in any free area of the yard. When we need them, we just call "white dogs come here!". And all the white dogs run with us for a walk to the park.

Difference between retrieving and referencing

The database distinguishes retrieving operation from reverencing it. Retrieving means actually getting data by calling the remote server and retrieving real values of records. Unlike retrieving, referencing operation does not call the Firebase server. It just saved address of data into certain variable. That variable can be used in the future for actual retrieving. For the purposes of this post, I consider adding data under the retrieving section also, because adding data actually connects to the database, not merely creating a reference.
So in terms of postal office, referencing is like writing an address on an envelope. And retrieving is actually mailing an envelope and getting a response.

Retrieving

Add data to Firestore collection

Credits to native Firebase manual
val cities = db.collection("cities")

val data1 = hashMapOf(
       
"name" to "San Francisco",
       
"state" to "CA",
       
"country" to "USA",
       
"capital" to false,
       
"population" to 860000,
       
"regions" to listOf("west_coast", "norcal")
)
cities
.document("SF").set(data1)

Retrieve filtered collection

Credits to native Firebase manual.

db.collection("cities")
       
.whereEqualTo("capital", true)
       
.get()
       
.addOnSuccessListener { documents ->
           
for (document in documents) {
               
Log.d(TAG, "${document.id} => ${document.data}")
           
}
       
}
       
.addOnFailureListener { exception ->
           
Log.w(TAG, "Error getting documents: ", exception)
       
}

Referencing

Reference filtered collection

Credits to native Firebase manual.

citiesRef.whereNotEqualTo("capital", false)

Reference certain document

First way to reference the document:
val alovelaceDocumentRef = db.collection("users").document("alovelace")
Another way to reference the document:
val alovelaceDocumentRef = db.document("users/alovelace")

No comments:

Post a Comment