You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
dependencies {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:25.12.0')
// Declare the dependency for the Cloud Firestore library// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-firestore-ktx'
}
Cloud Firestore - 안드로이드 앱 - 레퍼런스 객체
Collection이나 Document에 대한 레퍼런스를 얻고,
Collection 레퍼런스를 통해
Document 추가/삭제
Document 레퍼런스를 통해
필드 추가/변경/삭제
Collection 추가/삭제
val db:FirebaseFirestore=Firebase.firestore
val itemsCollectionRef = db.collection("items") // items는 Collection ID
itemCollectionRef.document( ID ) 를 하면 items Collection 밑에 있는 Document에 대한 레퍼런스를 의미
Cloud Firestore - 안드로이드 앱 - 레퍼런스 객체
collection()과 document() 메소드를 레퍼런스에 적용하여 하위 데이터 레퍼런스를 얻거나
val price = binding.editPrice.text.toString().toInt()
val autoID = binding.checkAutoID.isChecked
val itemID = binding.editID.text.toString()
val itemMap = hashMapOf(
"name" to name,
"price" to price
)
if (autoID) { // Document의 ID를 자동으로 생성
itemsCollectionRef.add(itemMap)
.addOnSuccessListener { updateList()
}.addOnFailureListener { }
} else { // Document의 ID를 itemID의 값으로 지정
itemsCollectionRef.document(itemID).set(itemMap)
.addOnSuccessListener { updateList()
}.addOnFailureListener { }
// itemID에 해당되는 Document가 존재하면 내용을 업데이트
}
Cloud Firestore - 안드로이드 앱 - 데이터 추가
데이터 추가된 결과를 firebase console에서 확인
Cloud Firestore - 안드로이드 앱 - 데이터 읽기
Collection의 Document 모두 읽기
레퍼런스에 get() 메소드 이용
비동기 연산 결과를 리스너로 받음
privatefunupdateList() {
itemsCollectionRef.get().addOnSuccessListener { // it: QuerySnapshotval items = mutableListOf<Item>()
for (doc in it) {
items.add(Item(doc)) // Item의 생성자가 doc를 받아 처리
}
adapter?.updateList(items)
}
}
// snapshot listener for all items
snapshotListener = itemsCollectionRef.addSnapshotListener { snapshot, error ->
binding.textSnapshotListener.text =StringBuilder().apply {
for (doc in snapshot!!.documentChanges) {
append("${doc.type}${doc.document.id}${doc.document.data}")
}
}
}
// sanpshot listener for single item
itemsCollectionRef.document( DocumentID ).addSnapshotListener { snapshot, error ->Log.d(TAG, "${snapshot?.id}${snapshot?.data}")
}
...
snapshotListener?.remove()
Cloud Firestore - 안드로이드 앱 - 데이터 조건 검색
Collection에서 조건을 주고 Document를 검색
privatefunqueryWhere() {
val p =100
itemsCollectionRef.whereLessThan("price", p).get()
.addOnSuccessListener {
val items = arrayListOf<String>()
for (doc in it) {
items.add("${doc["name"]} - ${doc["price"]}")
}
AlertDialog.Builder(this)
.setTitle("Items which price less than $p")
.setItems(items.toTypedArray(), { dialog, which -> }).show()
}
.addOnFailureListener {
}
}
Cloud Firestore - 안드로이드 앱 - 데이터 조건 검색
예제의 whereLessThan 외에도
whereEqualTo : ==
whereLessThanOrEqualTo : <=
whereGreaterThan : >
whereGreaterThanOrEqualTo : >=
whereNotEqualTo : !=
whereArrayContains : 필드 값이 배열이고, 필드에 특정 값 포함 여부
whereArrayContainsAny : 필드 값이 배열이고, 인자로 준 배열의 값 중 하나라도 포함하는지 여부
dependencies {
// Import the BoM for the Firebase platform
implementation platform('com.google.firebase:firebase-bom:25.12.0')
// Declare the dependency for the Realtime Database library// When using the BoM, you don't specify versions in Firebase library dependencies
implementation 'com.google.firebase:firebase-database-ktx'
}
Realtime Database - 안드로이드 앱 - 레퍼런스 가져오기
Firebase.database.getReference( 경로명 )
val database =Firebase.database
val itemsRef = database.getReference("items")
루트의 items에 대한 레퍼런스
레퍼런스의 child( 경로명 ) 메소드로 자식 노드의 레퍼런스 가져옴
itemsRef.child("123").child("name")
Realtime Database - 안드로이드 앱 - 데이터 쓰기
데이터베이스 레퍼런스를 가져와서 setValue()를 호출하여 씀
val name = binding.editItemName.text.toString()
val price = binding.editPrice.text.toString().toInt()
val autoID = binding.checkAutoID.isChecked
val itemID = binding.editID.text.toString()
val itemMap = hashMapOf( // 여러 자식(키,값)을 한번에 쓰기"name" to name,
"price" to price
)
if (autoID) { // key를 자동으로 생성val itemRef = itemsRef.push()
itemRef.setValue(itemMap)
} else { // 주어진 itemID로 키를 만듬val itemRef = itemsRef.child(itemID)
itemRef.setValue(itemMap)
}
Realtime Database - 안드로이드 앱 - 데이터 읽기
ValueEventListener를 등록, 해당 값이 변경될 때마다 알려줌
ValueEventListener등록을 취소: removeEventListener()
itemsRef.addValueEventListener(object:ValueEventListener {
overridefunonDataChange(dataSnapshot:DataSnapshot) {
val items = mutableListOf<Item>()
for (child in dataSnapshot.children) {
items.add(Item(child.key ?:"", child.value asMap<*, *>))
}
adapter?.updateList(items)
}
overridefunonCancelled(error:DatabaseError) {
// Failed to read value
}
})
Realtime Database - 안드로이드 앱 - 데이터 읽기
ValueEventListener를 등록하고 한번만 알려주길 원하면 addListenerForSingleValueEvent()를 사용
privatefunqueryItem(itemID:String) {
itemsRef.child(itemID).addListenerForSingleValueEvent(object:ValueEventListener {
overridefunonDataChange(dataSnapshot:DataSnapshot) {
val map = dataSnapshot.value asMap<*, *>
binding.editID.setText(itemID)
binding.editItemName.setText(map["name"].toString())
binding.editPrice.setText(map["price"].toString())
}
overridefunonCancelled(error:DatabaseError) {
// Failed to read value
}
})
}
Realtime Database - 안드로이드 앱 - 데이터 쓰기/변경
업데이트 하려는 레퍼런스를 찾아서 setValue()
해당 노드가 없으면 새로 만들게 됨
val itemID = binding.editID.text.toString()
val price = binding.editPrice.text.toString().toInt()
itemsRef.child(itemID).child("price").setValue(price)
.addOnSuccessListener { queryItem(itemID) }
updateChildren() 으로 자식 키/값을 한번에 업데이트
val itemMap = hashMapOf(
"price" to price
)
itemsRef.child(itemID).updateChildren(itemMap asMap<String, Any>)
.addOnSuccessListener { queryItem(itemID) }
Realtime Database - 안드로이드 앱 - 데이터 삭제
삭제하려는 노드 레퍼런스 찾아서 removeValue()
privatefundeleteItem() {
val itemID = binding.editID.text.toString()
if (itemID.isEmpty()) {
Snackbar.make(binding.root, "Input ID!", Snackbar.LENGTH_SHORT).show()
return
}
itemsRef.child(itemID).removeValue()
.addOnSuccessListener { }
}
Realtime Database - 안드로이드 앱 - 트랜잭션
트랜잭션 처리, runTransaction()
privatefunincrPrice() {
val itemID = binding.editID.text.toString()
if (itemID.isEmpty()) {
Snackbar.make(binding.root, "Input ID!", Snackbar.LENGTH_SHORT).show()
return
}
itemsRef.child(itemID).child("price")
.runTransaction(object:Transaction.Handler {
overridefundoTransaction(mutableData:MutableData): Transaction.Result {
var p = mutableData.value.toString().toIntOrNull() ?:0
p++
mutableData.value = p
returnTransaction.success(mutableData)
}
overridefunonComplete(
databaseError:DatabaseError?,
committed:Boolean,
currentData:DataSnapshot?
) {
// Transaction completed
queryItem(itemID)
}
})
}
Realtime Database - 안드로이드 앱 - 데이터 정렬
데이터 정렬: orderByChild(), orderByKey(), orderByValue()
val query = itemsRef.orderByChild("price")
query.addValueEventListener(object:ValueEventListener {
overridefunonDataChange(dataSnapshot:DataSnapshot) {
for (child in dataSnapshot.children) {
println("${child.key} - ${child.value}")
}
}
overridefunonCancelled(error:DatabaseError) {
// Failed to read value
}
})
결과 수 제한: limitToFirst(), limitToLast()
val query = itemsRef.orderByChild("price").limitToFirst(100)