今天要使用 Firebase 提供的資料庫功能來存放資料
首先開啟一個空白的專案
然後在 IDE 上方的選單選擇 Tools -> Firebase
接著畫面右邊會彈出選單,選擇 Realtime Database
按下 Save and retrieve data
這邊有兩個基本動作要做,首先是連接到 Firebase
第一次連接時有跳出連接失敗訊息,但似乎還是有連接上,再重按一次會跳出同步訊息,再按同步就可以了
第二步是把相關的 package 加到專案之中,按下按鈕後 IDE 會幫我們自動加入
自動加入的版本會比較舊,可以到 build.gradle 中手動更新
implementation 'com.google.firebase:firebase-database:16.0.5'
綁定和設置完成後就可以在 Firebase Console 中看到自己的專案
點擊進入之後,可以看到畫面 package 名稱後面有一個小紅點
按下後選擇繼續設定 sdk,然後下載它提供的 json 檔案並放到提示的路徑之中
(專案目錄/app 底下,可能需要關掉 IDE 才能覆蓋檔案)
下一步的 gradle 設定跟 IDE 幫我們帶入的大致相同,但是多一行
implementation 'com.google.firebase:firebase-core:16.0.5'
不知什麼原因,從 IDE 設定並沒有帶入這一行
最後在手機上執行過一次 APP,就可以驗證是否安裝成功了。
再來要寫程式把資料儲存到 Firebase 上,先到網頁上的控制台新增資料庫
我們這次使用的是 Realtime Database,要注意別選錯
資料庫建立起來之後,回到 MainActivity
首先建立三個會使用到的變數
private var fireDB = FirebaseDatabase.getInstance()
private var dbRef: DatabaseReference = fireDB.getReference("Users")
private var list: MutableList<User> = mutableListOf()
在 Realtime Database 中是用偵聽的方式去接收資料
首先寫一個方法來處理 addListenerForSingleValueEvent
這個方法只會執行一次而且是立即執行
覆寫 onDataChange 事件可以得到目前資料庫上的資料
把它取出來後轉型,再放到我們處理資料的 list 中
然後顯示在畫面上
private fun setSingleValueEvent() {
dbRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError) {}
override fun onDataChange(dataSnapshot: DataSnapshot) {
if (dataSnapshot.exists()) {
for (item in dataSnapshot.children) {
val user = item.getValue(User::class.java)
list.add(user!!)
}
show()
}
}
})
}
下一步是處理子節點的偵聽
這邊關注新增和刪除的部分
一樣是偵測到新增的時候,會觸發 onChildAdded ,再把得到的值從雲端存到我們的 list 中,再刷新畫面。
刪除一樣,在偵測到刪除節點的時候,會觸發 onChildRemoved ,這裡使用 lambda 去找出那個擁有那個 uid 的 user,然後從 list 中移除,刷新畫面。
private fun setChildEvent() {
dbRef.addChildEventListener(object : ChildEventListener {
override fun onCancelled(p0: DatabaseError) {}
override fun onChildMoved(p0: DataSnapshot, p1: String?) {}
override fun onChildChanged(p0: DataSnapshot, p1: String?) {}
override fun onChildAdded(p0: DataSnapshot, p1: String?) {
val user = p0.getValue(User::class.java)
list.add(user!!)
show()
}
override fun onChildRemoved(p0: DataSnapshot) {
val user = p0.getValue(User::class.java)
list.remove(list.first { x -> x.uid == user!!.uid })
show()
}
})
}
顯示資料,單純把 list 中的資料放到 TextView
private fun show() {
var txt = ""
for (user in list) {
txt += "${user.name} ${user.age} ${user.tel}\n"
}
textView.text = txt
}
新增按鈕按下時,新增一個我們自訂的 User 類別 (這邊寫固定資料,只展示效果)
再利用 DatabaseReference.child 找到節點,然後給值
這邊給值之後,網路上的資料有變動,就會觸發上面設定的 onChildAdded 事件
private fun add() {
val uid: String = UUID.randomUUID().toString()
val user = User(uid, "Ben", "15", "01234")
dbRef.child(uid).setValue(user)
}
這邊直接做移除全部的資料
一樣是透過 DatabaseReference 移除某個節點
每個節點被移除時就會觸發上面設定的 onChildRemoved 事件
private fun clearAll() {
for (user in list) {
dbRef.child(user.uid).removeValue()
}
}
附上 onCreate 方法
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSingleValueEvent()
setChildEvent()
add.setOnClickListener { add() }
clear.setOnClickListener { clearAll() }
}
不好意思,我再匯入firebase的時候一直出現錯誤
我用的是android8.0和7.1.1兩個都不行
我有看到國外的論壇說的是版本衝突,我也試了很多次都是一樣
請問有什麼方法解決嗎?
謝謝
dependencies 中最下方 firebase-database 版本改成:
implementation 'com.google.firebase:firebase-database:16.0.5' 試看看