Android/FireBase Series: [#02] — Firebase Firestore

Leo N
5 min readMar 28, 2020

Agenda

Android: FireBase + Kotlin Part 1 (Remote Config)

Android: FireBase + Kotlin Part 2 (Firebase Firestore)

Android: FireBase + Kotlin Part 3 (Firebase Realtime Database)

Firestore

Use our flexible, scalable NoSQL cloud database to store and sync data for client- and server-side development. Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud Platform. Like Firebase Realtime Database, it keeps your data in sync across client apps through realtime listeners and offers offline support for mobile and web so you can build responsive apps that work regardless of network latency or Internet connectivity. Cloud Firestore also offers seamless integration with other Firebase and Google Cloud Platform products, including Cloud Functions.

  • Flexibility: The Cloud Firestore data model supports flexible, hierarchical data structures. Store your data in documents, organized into collections. Documents can contain complex nested objects in addition to subcollections.
  • Expressive querying: In Cloud Firestore, you can use queries to retrieve individual, specific documents or to retrieve all the documents in a collection that match your query parameters. Your queries can include multiple, chained filters and combine filtering and sorting. They’re also indexed by default, so query performance is proportional to the size of your result set, not your data set.
  • Realtime updates: Like Realtime Database, Cloud Firestore uses data synchronization to update data on any connected device. However, it’s also designed to make simple, one-time fetch queries efficiently.
  • Offline support: Cloud Firestore caches data that your app is actively using, so the app can write, read, listen to, and query data even if the device is offline. When the device comes back online, Cloud Firestore synchronizes any local changes back to Cloud Firestore.
  • Designed to scale: Cloud Firestore brings you the best of Google Cloud Platform’s powerful infrastructure: automatic multi-region data replication, strong consistency guarantees, atomic batch operations, and real transaction support. We’ve designed Cloud Firestore to handle the toughest database workloads from the world’s biggest apps.

How does it work?

Cloud Firestore is a cloud-hosted, NoSQL database that your iOS, Android, and web apps can access directly via native SDKs. Cloud Firestore is also available in native Node.js, Java, Python, Unity, C++ and Go SDKs, in addition to REST and RPC APIs.

Following Cloud Firestore’s NoSQL data model, you store data in documents that contain fields mapping to values. These documents are stored in collections, which are containers for your documents that you can use to organize your data and build queries. Documents support many different data types, from simple strings and numbers, to complex, nested objects. You can also create subcollections within documents and build hierarchical data structures that scale as your database grows. The Cloud Firestore data model supports whatever data structure works best for your app.

Additionally, querying in Cloud Firestore is expressive, efficient, and flexible. Create shallow queries to retrieve data at the document level without needing to retrieve the entire collection, or any nested subcollections. Add sorting, filtering, and limits to your queries or cursors to paginate your results. To keep data in your apps current, without retrieving your entire database each time an update happens, add realtime listeners. Adding realtime listeners to your app notifies you with a data snapshot whenever the data your client apps are listening to changes, retrieving only the new changes.

Protect access to your data in Cloud Firestore with Firebase Authentication and Cloud Firestore Security Rules for Android, iOS, and JavaScript, or Identity and Access Management (IAM) for server-side languages.

When to use Cloud Firestore database?

  • Firestore in Datastore mode uses Datastore system behavior but accesses Firestore’s storage layer, removing the following Datastore limitations:
  • Eventual consistency, all Datastore queries become strongly consistent.
  • Queries in transactions are no longer required to be ancestor queries.
  • Transactions are no longer limited to 25 entity groups.
  • Writes to an entity group are no longer limited to 1 per second.

Datastore mode disables Firestore features that are not compatible with Datastore:

  • The project will accept Datastore API requests and deny Firestore API requests.
  • The project will use Datastore indexes instead of Firestore indexes.
  • You can use Datastore client libraries with this project but not Firestore client libraries.
  • Firestore real-time capabilities will not be available.
  • In the Cloud Console, the database will use the Datastore viewer.

Working with data

Cloud Firestore is nothing but a cloud hosted database NoSQL data model which saves data in documents contains fields mapping to values. Documents are organised in Collections. Cloud Firestore is optimized for storing large collections of small documents. Documents can contain sub collections and nested objects, both of which can include primitive fields like strings or complex objects like lists.

Cloud Firestore Documents data supports following data types:

  • Array — Sort by elements if not same else by length
  • Boolean — false or true
  • Bytes . Only first 1500 bytes are considered by the queries
  • Date Time — Chronological
  • Float — numeric — floating point number
  • Geographical point — by latitude then longitude
  • Int — numeric — Integer number
  • Map — key value — example {“foo”: “bar”}
  • null — None
  • Reference — path elements — project/[ID]/some/thing/doc/here
  • Text String — UTF-8 encoded byte

Pricing

https://cloud.google.com/firestore/pricing

Stop talking, code now!!

api 'com.google.firebase:firebase-firestore-ktx:NewestVersion'

Features

Get an instance of FirebaseFirestore

Kotlin

val firestore = FirebaseFirestore.getInstance()
val anotherFirestore = FirebaseFirestore.getInstance(FirebaseApp.getInstance("myApp"))

Kotlin + KTX

val firestore = Firebase.firestore
val anotherFirestore = Firebase.firestore(Firebase.app("myApp"))

Convert a DocumentSnapshot field to a POJO

Kotlin

val snapshot: DocumentSnapshot = ...
val myObject = snapshot.get("fieldPath", MyClass::class.java)

Kotlin + KTX

val snapshot: DocumentSnapshot = ...
val myObject = snapshot.get<MyClass>("fieldPath")

Convert a DocumentSnapshot to a POJO

Kotlin

val snapshot: DocumentSnapshot = ...
val myObject = snapshot.toObject(MyClass::class.java)

Kotlin + KTX

val snapshot: DocumentSnapshot = ...
val myObject = snapshot.toObject<MyClass>()

Convert a QuerySnapshot to a list of POJOs

Kotlin

val snapshot: QuerySnapshot = ...
val objectList = snapshot.toObjects(MyClass::class.java)

Kotlin + KTX

val snapshot: QuerySnapshot = ...
val objectList = snapshot.toObjects<MyClass>()

Setup Firestore with a local emulator

Kotlin

val settings = FirebaseFirestoreSettings.Builder()
.setHost("10.0.2.2:8080")
.setSslEnabled(false)
.setPersistenceEnabled(false)
.build()
firestore.setFirestoreSettings(settings)

Kotlin + KTX

firestore.firestoreSettings = firestoreSettings {
host = "http://10.0.0.2:8080"
isSslEnabled = false
isPersistenceEnabled = false
}

Thanks for:

--

--

Leo N

🎓 “A person who never made a mistake never tried anything new.” — Albert Einstein