Android-在Firestore新增資料

Vincent Zheng
新手工程師的程式教室
5 min readDec 23, 2018

Firestore的資料儲存單位是文件(document),而文件中的內容是「欄位與值」的關係,跟關聯式資料庫有點像。在程式設計中,有兩種資料類型也是類似這樣的形式:「類別物件」與「Map」。

本節將帶領讀者分別用這兩種方式新增資料,並配置在執行完畢後所要觸發的程式流程。使用的是Kotlin語言。

一、用類別物件來定義資料

首先請在Android專案中新建一個自訂類別:

class Student(
var stuId: Int = 0,
var name: String = "",
var birthday: String = "") {
}

這是一個「學生」的類別,裡頭定義了三個資料欄位,並且它們都有各自的值。接下來請設定好這些欄位的值:

val student1 = Student()student1.stuId = 10346098
student1.name = "Eric"
student1.birthday = "1996/12/31"

二、用Map來定義資料

Map是透過「key-value」的形式來儲存資料。假設我們要在資料庫新增「學生」的資料,可以像下面這樣定義好所需欄位的值:

val student2 = HashMap<String, Any>()student2["stuId"] = 10346099
student2["name"] = "Vincent"
student2["birthday"] = "1996/01/01"
student2["department"] = "Information Management"

這種方式的特色是可以任意地增減資料欄位,想放什麼資料就放什麼。如果是使用自訂類別所產生的物件,就只能使用原類別既有的欄位。

三、新增資料並設定callback程式

資料定義好後,使用資料庫物件的「add」方法來新增,這樣就行了。

資料庫物件.collection("集合名稱").add(要新增的物件)db.collection("Students").add(student1)
db.collection("Students").add(student2)
使用Map新增的資料

但若希望在資料新增完成後,能夠進行一些工作,例如離開畫面、提示訊息,或是取得文件ID作其他用途,此時就需要配置callback程式:

db.collection("Students")
.add(student1)
.addOnCompleteListener { task: Task<DocumentReference> ->
// 要進行的工作
}

add方法或其他對Firestore的操作,都牽涉到網路傳輸。配置callback程式是為了「等待」傳輸完畢後才自動被執行,如同按鈕的點擊事件也是等待被執行。這裡都是透過附加Listener的方式來處理。

首先介紹「OnCompleteListener」,當網路傳輸完成後會被觸發。這裡會得到一個Task類型的物件,裡面有這次任務的執行結果,以下是幾個範例。

db.collection("Students")
.add(student1)
.addOnCompleteListener { task: Task<DocumentReference> ->
if (task.isSuccessful) {
Toast.makeText(applicationContext, "新增成功\n" + task.result.id, Toast.LENGTH_SHORT).show()
finish()
} else {
Toast.makeText(applicationContext, "新增失敗\n" + task.exception.toString(), Toast.LENGTH_SHORT).show()
}
}
  1. Task.isSuccessful:任務執行成功或失敗
  2. Task.result:取得剛剛新增的文件(document)的實體物件
  3. Task.exception:取得例外物件

上面這段程式是判斷任務執行結果來顯示不同的訊息。成功時會顯示文件的ID,並離開當前畫面。失敗則會出現錯誤訊息。

其他Listener包括「OnSuccessListener」和「OnFailureListener」。前者會得到DocumentReference物件,後者會得到Exception物件,正好對應到上述的第2、3點。

若要使用這兩項來改寫,會像下面這樣子:

db.collection("Students")
.add(student2)
.addOnSuccessListener { documentReference: DocumentReference ->
Toast.makeText(applicationContext, "新增成功\n" + documentReference.id, Toast.LENGTH_SHORT).show()
finish()
}
.addOnFailureListener { exception: Exception ->
Toast.makeText(applicationContext, "新增失敗\n" + exception.toString(), Toast.LENGTH_SHORT).show()
}

也就是說能拆開撰寫,省去「Task.isSuccessful」的判斷。若程式需求是只有成功或只有失敗才進行額外的工作,不妨單獨使用「OnSuccessListener」或「OnFailureListener」。

--

--

Vincent Zheng
新手工程師的程式教室

我是Vincent,是個來自資管系的後端軟體工程師。當初因為學校作業,才踏出寫部落格的第一步。這裡提供程式教學文章,包含自學和工作上用到的經驗,希望能讓讀者學到東西。我的部落已搬家至 https://chikuwa-tech-study.blogspot.com/