Firebase cloud firestore

Firebase是一家實(shí)時(shí)后端數(shù)據(jù)庫(kù)創(chuàng)業(yè)公司,它能幫助開(kāi)發(fā)者很快的寫(xiě)出Web端和移動(dòng)端的應(yīng)用,無(wú)需管理基礎(chǔ)架構(gòu),快速構(gòu)建您的應(yīng)用。自2014年10月Google收購(gòu)Firebase以來(lái),用戶(hù)可以在更方便地使用Firebase的同時(shí),結(jié)合Google的云服務(wù)。

Cloud Firestore 官方文檔

Cloud Firestore 和 Realtime Database進(jìn)行對(duì)比

  1. Cloud Firestore 是firebase提供的新型數(shù)據(jù)庫(kù),相比于Realtime Database更直觀的展現(xiàn)數(shù)據(jù),更快的查詢(xún),功能列強(qiáng)大
  2. 都支持離線(xiàn)模式
  3. 實(shí)時(shí)數(shù)據(jù)庫(kù)和 Cloud Firestore 都是 NoSQL 數(shù)據(jù)庫(kù)。
  4. 實(shí)時(shí)數(shù)據(jù)庫(kù)將數(shù)據(jù)存儲(chǔ)為一個(gè)大型 JSON 樹(shù),Cloud Firestore 將數(shù)據(jù)存儲(chǔ)為文檔集合。

數(shù)據(jù)模型

  1. 文檔 - 在 Cloud Firestore中,存儲(chǔ)單元是文檔。文檔是一個(gè)輕量級(jí)記錄,包含映射到值的字段。每個(gè)文檔都用一個(gè)名稱(chēng)進(jìn)行標(biāo)識(shí)
  2. 集合 - 文檔存在于集合中,而集合只是文檔的容器
    您無(wú)需“創(chuàng)建”或“刪除”集合。在集合中創(chuàng)建第一個(gè)文檔之后,集合才會(huì)存在。如果刪除集合中的所有文檔,集合將不再存在。
    所以文檔結(jié)構(gòu)可以是coll/doc/subcoll/subdoc 可以一直嵌套
    [圖片上傳失敗...(image-c8ba6a-1592561180755)]

向 Cloud Firestore 添加數(shù)據(jù)

  1. 在集合中設(shè)置文檔的數(shù)據(jù),并明確指定一個(gè)文檔標(biāo)識(shí)符
  2. 向集合添加新文檔。在這種情況下,Cloud Firestore 會(huì)自動(dòng)生成文檔標(biāo)識(shí)符。
  3. 在文檔下面添加相應(yīng)的數(shù)據(jù)

舉個(gè)例子,例如先自定義對(duì)象

data class User(val name: String, val age: Int)

往firestore建立的document michat/users/ 目錄下寫(xiě)入具體數(shù)據(jù),此時(shí)指定了文檔id為users

val mDocRef = FirebaseFirestore.getInstance().collection("michat").document("users")
mDocRef.set(User(nameView.text.toString(), ageView.text.toString().toInt()))
                .addOnSuccessListener {
                    Log.d("FirstFragment", "save success......")
                    Toast.makeText(context, "save success", Toast.LENGTH_LONG).show()
                }
                .addOnFailureListener {
                    Log.d("FirstFragment", "save failed......$it")
                    Toast.makeText(context, "save failed", Toast.LENGTH_LONG).show()
                }

如果有時(shí)無(wú)法為文檔指定有意義的 ID,讓 Cloud Firestore 為您自動(dòng)生成 ID 會(huì)比較方便。您可以通過(guò)調(diào)用 add() 來(lái)實(shí)現(xiàn)此目的:

// Add a new document with a generated id.
val data = hashMapOf(
        "name" to "Tokyo",
        "country" to "Japan"
)

db.collection("cities")
    .add(data)
    .addOnSuccessListener { documentReference ->
        Log.d(TAG, "DocumentSnapshot written with ID: ${documentReference.id}")
    }
    .addOnFailureListener { e ->
        Log.w(TAG, "Error adding document", e)
    }

如果是只更新某個(gè)字段,而不是全覆蓋,也是支持的

mDocRef.update("name", "wangbin-update")

遞增數(shù)值
您可以遞增或遞減數(shù)字字段值,如以下示例所示。遞增或遞減操作會(huì)在字段的當(dāng)前值基礎(chǔ)上增加或減少給定數(shù)量。如果該字段不存在或者當(dāng)前字段值不是數(shù)值,則相應(yīng)操作會(huì)將該字段設(shè)置為給定值。這點(diǎn)在動(dòng)態(tài)配置時(shí)非常靈活

mDocRef.update("age", FieldValue.increment(10))

使用 Cloud Firestore 獲取數(shù)據(jù)

  1. 獲取單個(gè)文檔,如獲取nearby
    先定義nearby對(duì)象用來(lái)解析數(shù)據(jù)
class NearBy : Serializable {
    var ad: Ad? = null
    var alias: String = ""
    override fun toString(): String {
        return "${ad?.flag}, ${ad?.index}, $alias"
    }
}

class Ad : Serializable {
    var flag: Boolean = false
    var index: String = ""
}

通過(guò)get來(lái)成功獲取firestore上的nearby文檔

val docRef = FirebaseFirestore.getInstance().collection("michat").document("nearby")
        fetchBtn.setOnClickListener {
            docRef.get().addOnSuccessListener {
                if (it.exists()) {
                    val result = it.toObject(NearBy::class.java)
                    Log.d("FirstFragment", "fetch success......$result")
                    desTv.text = "fetch result:$result"
                    Toast.makeText(context, "fetch success", Toast.LENGTH_LONG).show()
                }
            }
                .addOnFailureListener {
                    Log.d("FirstFragment", "fetch failed......$it")
                    Toast.makeText(context, "fetch failed", Toast.LENGTH_LONG).show()
                }
        }
  1. 從集合中獲取多個(gè)文檔
    您還可以查詢(xún)某個(gè)集合中的文檔,從而使用一個(gè)請(qǐng)求檢索多個(gè)文檔。例如,您可以使用 where() 來(lái)查詢(xún)滿(mǎn)足特定條件的所有文檔,然后使用 get() 檢索結(jié)果:
FirebaseFirestore.getInstance().collection("michat")
            .whereEqualTo("alias", "test").get()
            .addOnSuccessListener {
                Log.d("FirstFragment", "query success result:$it")
                it.forEach { queryDocumentSnapshot ->
                    Log.d("FirstFragment", "query success result:$queryDocumentSnapshot")
                }
            }
            .addOnFailureListener {
                Log.d("FirstFragment", "query failed result:$it")
            }

就能查出包含文檔nearby的集合

  1. 支持?jǐn)?shù)據(jù)庫(kù)查詢(xún)排序
  • 簡(jiǎn)單查詢(xún)?nèi)缟厦?code>whereEqualTo
  • 復(fù)合查詢(xún)whereEqualTo("state", "CO").whereEqualTo("name", "Denver")
  • 對(duì)數(shù)據(jù)進(jìn)行排序citiesRef.whereGreaterThan("population", 100000).orderBy("population").limit(2),只返回人口超過(guò)100000的前兩個(gè)城市

使用 Cloud Firestore 獲取實(shí)時(shí)更新

  1. 如實(shí)時(shí)監(jiān)聽(tīng)cloud firestore的變化,可以文檔設(shè)置監(jiān)聽(tīng)
val docRef = FirebaseFirestore.getInstance().collection("michat").document("nearby")
// 監(jiān)聽(tīng)某一document的變化
 val registration = docRef.addSnapshotListener(object : EventListener<DocumentSnapshot>{
            override fun onEvent(documentSnapshot: DocumentSnapshot?, exception: FirebaseFirestoreException?) {
                val result = documentSnapshot?.toObject(NearBy::class.java)
                Log.d("FirstFragment", "onEvent listener result$result")
                desTv.text = "fetch result:$result"
            }

        })

這樣就可以設(shè)置對(duì)文檔nearby這一層級(jí)的監(jiān)聽(tīng)。對(duì)于實(shí)時(shí)性非常高的場(chǎng)景,就可以使用監(jiān)聽(tīng);通過(guò)documentSnapshot.metadata.isFromCache來(lái)判斷數(shù)據(jù)是來(lái)自本地緩存或者是來(lái)自服務(wù)器

  1. 分離監(jiān)聽(tīng)器
    當(dāng)不再需要監(jiān)聽(tīng)數(shù)據(jù)時(shí),您必須分離監(jiān)聽(tīng)器,以便停止調(diào)用事件回調(diào)函數(shù)。這樣客戶(hù)端可以停止使用帶寬來(lái)接收更新。例如
registration.remove()

離線(xiàn)訪(fǎng)問(wèn)數(shù)據(jù)

  1. 對(duì)于 Android 版和 iOS 版應(yīng)用,離線(xiàn)持久化默認(rèn)為啟用狀態(tài)。如需停用持久化,請(qǐng)將 PersistenceEnabled 選項(xiàng)設(shè)置為 false
    也可以在初始化的時(shí)候停用離線(xiàn)持久化
val settings = FirebaseFirestoreSettings.Builder()
        .setPersistenceEnabled(true)
        .build()
db.firestoreSettings = settings
  1. 當(dāng)設(shè)備在線(xiàn)時(shí)會(huì)優(yōu)先從網(wǎng)絡(luò)獲取文檔;如果您在設(shè)備離線(xiàn)時(shí)獲取文檔,Cloud Firestore 會(huì)從緩存中返回?cái)?shù)據(jù)。如果緩存不包含該文檔的數(shù)據(jù),或該文檔不存在,則 get 調(diào)用會(huì)返回一個(gè)錯(cuò)誤。
  2. 配置緩存大小
    啟用持久化后,Cloud Firestore 會(huì)緩存從后端接收的每個(gè)文檔以便離線(xiàn)訪(fǎng)問(wèn)。Cloud Firestore 為緩存大小設(shè)置默認(rèn)閾值。超出默認(rèn)值后,Cloud Firestore 會(huì)定期嘗試清理較舊的未使用文檔。您可以配置不同的緩存大小閾值,也可以完全停用清理過(guò)程:
// The default cache size threshold is 100 MB. Configure "setCacheSizeBytes"
// for a different threshold (minimum 1 MB) or set to "CACHE_SIZE_UNLIMITED"
// to disable clean-up.
val settings = FirebaseFirestoreSettings.Builder()
        .setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
        .build()
db.firestoreSettings = settings

codelab:
https://codelabs.developers.google.com/codelabs/firestore-android/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容