1. Compare Cloud Firestore and Realtime Database
Surely everyone knows there is a familiar type of database called Relational Database, so what is it different from Firestore? Here is a table showing the differences:
Concept | Firestore | Relational database |
---|---|---|
Programing language | NoSQL | SQL |
Category of object | Collection group | Table |
One object | Document | Row |
Individual data for an object | Field | Column |
Unique ID for an object | Document ID | Primary key |
In Firebase there are 2 types that are Cloud Firestore and Realtime Database, but why Cloud Firestore is mentioned more, let’s find out!
Firebase offers two cloud-based:
- Cloud Firestore is the latest Firebase database for mobile parties. It is built on top of Realtime Database with a new and more intuitive data model. Cloud Firestore also offers more features, faster querry and wider scale than Realtime Database.
- Realtime Database is the original Firebase database. It’s an efficient, low-latency solution for mibile apps that require state to be synchronized between clients in real time.
So which database is recommended by Firebase? The choice of which database to use depends on many factors, depending on specific features that the user can choose which database type is suitable.
Both databases share the following points:
- Client-first SDKs, do not need a server to deploy and maintain.
- Realtime updates
There are also some prominent differences as follows:
Cloud Firestore | Realtime Database | |
---|---|---|
Data model | + Store data in the form of collections and documents. + Simple data is stored in document, it is quite similar to JSON. + For complex, hierarchical data, it is also easier to organize by using subcollections linked to documents. + Fewer requirements for standardizing and compacting data | + Store data in the form of a large JSON tree. Simple data is also very easy to store. + With complex and decentralized data, it is more difficult to manage |
Querying | + Query with indexing and can use both sort and filter at the same time | + Deep query is limited, can only use sort or filter |
Writes and transactions | + Advanced writing and converting methods available. | + These methods are at the basic level |
See more details here !
Firestore’s data storage structure is as follows:
Documents : is the lowest structure, it can store from string to binary:
Collections : contains one or more documents, there are some rules for Collections as follows:
- Collection contains only document, no Collection string or Collection binary.
- Document cannot contain document, but it can point to a subCollection.
- The root of your database can only contain Collections.
An example of your database structure looks like this:
2. Create and setup a Cloud Firestore
Project installation
- Install firebase into the project, click here !
- In the project’s build.gradle file, add Google’s Maven repository in both buildscript and allprojects blocks.
- Add Cloud Firestore library to app / build.gradle file:
1 2 | implementation <span class="token string">'com.google.firebase:firebase-firestore-ktx:21.6.0'</span> |
Build app example
I design a view with 2 editText and a button, when I click on the button, I will save the data in these two editText to Firestore:
The code is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">private</span> val documentRef <span class="token operator">=</span> <span class="token class-name">FirebaseFirestore</span> <span class="token punctuation">.</span> <span class="token function">getInstance</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">document</span> <span class="token punctuation">(</span> <span class="token string">"sampleData/home"</span> <span class="token punctuation">)</span> <span class="token keyword">private</span> fun <span class="token function">setEvent</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> btnSend <span class="token punctuation">.</span> setOnClickListener <span class="token punctuation">{</span> val dataToSave <span class="token operator">=</span> <span class="token class-name">HashMap</span> <span class="token generics"><span class="token punctuation"><</span> <span class="token class-name">String</span> <span class="token punctuation">,</span> <span class="token class-name">Any</span> <span class="token punctuation">></span></span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> dataToSave <span class="token punctuation">[</span> <span class="token string">"KEY_NAME"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> editTextName <span class="token punctuation">.</span> text <span class="token punctuation">.</span> <span class="token function">toString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> dataToSave <span class="token punctuation">[</span> <span class="token string">"KEY_ROOM"</span> <span class="token punctuation">]</span> <span class="token operator">=</span> editTextRoom <span class="token punctuation">.</span> text <span class="token punctuation">.</span> <span class="token function">toString</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> documentRef <span class="token punctuation">.</span> <span class="token function">set</span> <span class="token punctuation">(</span> dataToSave <span class="token punctuation">)</span> <span class="token punctuation">.</span> addOnSuccessListener <span class="token punctuation">{</span> <span class="token class-name">Log</span> <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"-------->"</span> <span class="token punctuation">,</span> <span class="token string">"FirestoreFragment - initComponent: Add data success!"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> addOnFailureListener <span class="token punctuation">{</span> <span class="token class-name">Log</span> <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"-------->"</span> <span class="token punctuation">,</span> <span class="token string">"FirestoreFragment - initComponent: Add data failure!"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The first line is that I create an instance of Firebasestore. If there is no collection and document, it will be created on the console with the corresponding name in code. The structure of the collection and document is in the following format:
Okay, now I will create a rule on the console, go to Cloud Firestore on the console and click the Create database button, then it will open the rule setting screen to protect your data, the modes are for production or testing. I choose. Production mode, also known as Locked mode, does not allow a third party to read and write, commonly used for C #, Go, Java, Node.js, PHP, Python, or Ruby server client library. Test mode, on the other hand, allows anyone to read and write to the database, usually used by the web, iOS, or Android SDK.
Finished click the Next button:
Just click next until displaying the loading screen to create the database, when it is done it will be the main screen of the Firestore tab. After creating it, pay attention to the RULES tab, I have to edit to have the right to update the database:
1 2 3 4 5 6 7 8 9 10 11 12 | rules_version <span class="token operator">=</span> <span class="token string">'2'</span> <span class="token punctuation">;</span> service cloud <span class="token punctuation">.</span> firestore <span class="token punctuation">{</span> match <span class="token operator">/</span> databases <span class="token operator">/</span> <span class="token punctuation">{</span> database <span class="token punctuation">}</span> <span class="token operator">/</span> documents <span class="token punctuation">{</span> match <span class="token operator">/</span> sampleData <span class="token operator">/</span> <span class="token punctuation">{</span> anything <span class="token operator">=</span> <span class="token operator">*</span> <span class="token operator">*</span> <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow read <span class="token punctuation">,</span> write <span class="token operator">:</span> <span class="token keyword">if</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> match <span class="token operator">/</span> <span class="token punctuation">{</span> document <span class="token operator">=</span> <span class="token operator">*</span> <span class="token operator">*</span> <span class="token punctuation">}</span> <span class="token punctuation">{</span> allow read <span class="token punctuation">,</span> write <span class="token operator">:</span> <span class="token keyword">if</span> <span class="token boolean">false</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Finished and press the PUBLISH button:
Then I run the app and see the results on the console:
Now I do to get data from Firestore to display on TextView:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">private</span> fun <span class="token function">fetchData</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> documentRef <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> addOnSuccessListener <span class="token punctuation">{</span> documentSnapshot <span class="token operator">-></span> <span class="token keyword">if</span> <span class="token punctuation">(</span> documentSnapshot <span class="token punctuation">.</span> <span class="token function">exists</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> val name <span class="token operator">=</span> documentSnapshot <span class="token punctuation">.</span> <span class="token function">getString</span> <span class="token punctuation">(</span> KEY_NAME <span class="token punctuation">)</span> val room <span class="token operator">=</span> documentSnapshot <span class="token punctuation">.</span> <span class="token function">getString</span> <span class="token punctuation">(</span> KEY_ROOM <span class="token punctuation">)</span> textFetch <span class="token punctuation">.</span> text <span class="token operator">=</span> <span class="token string">"$name-----$room"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> addOnFailureListener <span class="token punctuation">{</span> <span class="token class-name">Log</span> <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"-------->"</span> <span class="token punctuation">,</span> <span class="token string">"FirestoreFragment - fetchData: Fail!"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
When you run the app up and press the Fetch button, it will retrieve data from Firestore:
Listen for realtime data updates about the app, put in onStart () so it listens:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | override fun <span class="token function">onStart</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">onStart</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> documentRef <span class="token punctuation">.</span> addSnapshotListener <span class="token punctuation">{</span> snapshot <span class="token punctuation">,</span> e <span class="token operator">-></span> <span class="token keyword">if</span> <span class="token punctuation">(</span> e <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">Log</span> <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"-------->"</span> <span class="token punctuation">,</span> <span class="token string">"FirestoreFragment - Listen fail!"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token annotation punctuation">@addSnapshotListener</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> snapshot <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> snapshot <span class="token punctuation">.</span> <span class="token function">exists</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> val name <span class="token operator">=</span> snapshot <span class="token punctuation">.</span> <span class="token function">getString</span> <span class="token punctuation">(</span> KEY_NAME <span class="token punctuation">)</span> val room <span class="token operator">=</span> snapshot <span class="token punctuation">.</span> <span class="token function">getString</span> <span class="token punctuation">(</span> KEY_ROOM <span class="token punctuation">)</span> textFetch <span class="token punctuation">.</span> text <span class="token operator">=</span> <span class="token string">"$name-----$room"</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token class-name">Log</span> <span class="token punctuation">.</span> <span class="token function">d</span> <span class="token punctuation">(</span> <span class="token string">"-------->"</span> <span class="token punctuation">,</span> <span class="token string">"FirestoreFragment - Data null!"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
result :
References
Firebase document: https://firebase.google.com/docs/firestore .