본문 바로가기
FireBase

Firebase -데이터베이스(3) 데이터 Read, Puul Driven방식, Push Driven 방식

by 봄석 2019. 1. 9.

Firebase - 데이터베이스 읽어오기(Read)

데이터베이스를 읽어오는 방식을 Read라고 합니다. 앱을 만드는데 있어서 Read부분은 굉장히 중요합니다. 데이터를 읽어오는 방식에는 두 가지가 있습니다. Controller가 자신이 원하는 타이밍에만 데이터베이스에 접근해서 데이터를 읽어오는 Pull Driven 방식과 , 데이터가 변경되는 순간 데이터를 받는 Push Driven 방식이 있습니다.


1.Pull Driven

Controller가 원하는 타이밍에 데이터를 읽어오는 방식입니다. 보통 한 번만 데이터를 읽어올 때 많이 사용합니다. Get().addOnCompleteListener를 입력해주면 됩니다.


형식

collection(Collection 이름).document(Document 이름).get().addOnCompeteListener{ task->
 
}



또한 Push Driven, Pull Driven 읽기 방식 말고도 데이터베이스를 읽어오는 방법두 가지가 있는데 첫 번째 Document 이름을 그대로 입력하는 방식과 

두 번째 Document 이름을 모를 경우 Query를 날려서 검색하는 방식이 있습니다.



[1]Document 이름을 입력하는 방식( 경로방식 데이터 읽어오기 )

Document 이름으로 데이터를 읽어오기는 가장 기본적인 방식으로 Document ID만 알고 있으면 Document의 내용들을 읽어올 수가 있습니다. 이 방식은 데이터를 검색하기 보다는 

이미 데이터에 대해 정확한 Collection과 Document ID 경로를 알고 있을 때 많이 사용합니다.


형식

collection(Collection 이름).document(Document 이름).get().addOnCompleteListener{
task->
}



간단히 Pull Driven 방식으로 경로방식의 데이터를 읽어오는 형식입니다.

정확한 경로인 Collection이름, Document 이름을 입력합니다. 

Document의 이름을 알 경우만 가능한 방법이며 


사용 예)

private fun readData(){
        firestore?.collection("User").document("document1").get()
            .addOnCompleteListener {
                if(it.isSuccessful){
                    var userDTO=it.result?.toObject(UserDTO::class.java)
                    toast(userDTO.toString())
                }
            }
    }



[2] Document 이름을 모를 경우(쿼리 방식 데이터 읽어오기)

반대로 Document의 이름을 모른다면 안에있는 데이터로만 검색해야 합니다.

즉, 쿼리를 이용해서 데이터를 가져와야 할것입니다.


우선 쿼리로 데이터를 읽어보기 전에 

UserDTO 데이터 모델에 age를 추가하겠습니다.

1
data class UserDTO(var name:String?=null,var address:String?=null,var age:Int?=null) 
cs

그리고 데이터를 몇개더 입력해줍니다.

firestore?.collection("User").document().set(UserDTO("캘시퍼","부산",5))
firestore?.collection("User").document().set(UserDTO("마르클","대전",9))

firestore?.collection("User").document().set(UserDTO("마녀","목포",70))


확인

추가된 내용을 확인해보겠습니다. , Document ID는 입력되는 시간에 따라 달라지므로 Document ID는 모두 다릅니다. 


이제 검색 Query의 종류 5가지에 대해 알아보겠습니다 .



검색 쿼리의 종류

1)WhereEqualTo

쿼리에 입력된 값이 같은 데이터를 검색하는 기능입니다. 정확히 한 글자도 틀리지 않고 검색 결과가 같아야 검색이 됩니다.   Firestore는 관계형 데이터베이스의 LIKE 검색이 되지않습니다.

하지만 LIKE 기능은 후에 안드로이드 내부에서 처리해보도록 하겠습니다.


입력 예)

private fun readQueryWhereEqulToData(){
        firestore?.collection("User").whereEqualTo("address","서울").get()
            .addOnCompleteListener {
                if(it.isSuccessful){
                    for(dc in it.result!!.documents){
                        var userDTO =dc.toObject(UserDTO::class.java)
                        toast(userDTO.toString())
                    }
                }
            }
    }


위 예를 실행해보면 address가 서울 인 Document만 검색됩니다.



2)WhereGreaterThan

쿼리에 입력된 값을 초과하는 데이터만 검색이 됩니다.


입력 예)

private fun readQueryWhereGreaterThanData(){
        firestore?.collection("User").whereGreaterThan("age",9).get()
            .addOnCompleteListener {
                if(it.isSuccessful){
                    for(dc in it.result!!.documents){
                        var userDTO = dc.toObject(UserDTO::class.java)
                        toast(userDTO.toString())
                    }
                }
            }
    }





3)WhereGreaterThanOrEqualTo

쿼리에 입력된 값보다 이상인 데이터만이 검색됩니다.


입력 예)

 private fun readQueryWhereGreaterThanOrEqualToData() {
        firestore?.collection("User").whereGreaterThanOrEqualTo("age", 9).get()
            .addOnCompleteListener {
                if (it.isSuccessful) {
                    for (dc in it.result!!.documents) {
                        var userDTO = dc.toObject(UserDTO::class.java)
                        println(userDTO.toString())
                    }
                }
            }
    }


결과

I/System.out: UserDTO(name=마르클, address=대전, age=9)

I/System.out: UserDTO(name=마녀, address=목포, age=70)




4)WhereLessThan

쿼리에 입력된 값의 미만 데이터만 검색됩니다.


입력 예)

   private fun readQueryWhereLessThanData(){
        firestore?.collection("User").whereLessThan("age",9).get()
            .addOnCompleteListener {
                if(it.isSuccessful){
                    for(dc in it.result!!.documents){
                        var userDTO =dc.toObject(UserDTO::class.java)
                        println(userDTO.toString())
                    }
                }
            }
    }



결과

I/System.out: UserDTO(name=캘시퍼, address=부산, age=5)



5)WhereLessThanOrEqualTO

쿼리에 입력된 값의 이하 데이터만 검색이 됩니다.


입력 예)

 private fun readQueryWhereLessThanOrEqualToData(){
        firestore?.collection("User").whereLessThanOrEqualTo("age",9).get()
            .addOnCompleteListener {
                if(it.isSuccessful){
                    for(dc in it.result!!.documents){
                        var userDTO =dc.toObject(UserDTO::class.java)
                        println(userDTO)
                    }
                }
            }
    }



결과


I/System.out: UserDTO(name=캘시퍼, address=부산, age=5)
I/System.out: UserDTO(name=마르클, address=대전, age=9)




2.Push Driven

데이터가 변경될 때마다 뷰를 그려주는 구조를 만들기 위해서 많이 사용한다. 특히 실시간으로 반영되는 리스트나 채팅을 만들 때 많이 사용합니다. 

사용 방법은 get.addOnCompleteListener 대신 addSnapshotListener를 써야합니다.


형식

collection(Collection 이름).document(Document 이름).addSnapshotListener{
documnetSnapshot, firebaseFirestoreException ->
 
}


Document Id로 넘색할 경우 Paramater로  documentSnapshot과 firebaseFirestoreException이 넘어온다.


입력 예)

private fun addSnapshotDocument(){
        firestore?.collection("User").document("document1")
            .addSnapshotListener { documentSnapshot, firebaseFirestoreException ->
                var document=documentSnapshot?.toObject(UserDTO::class.java)
                println(document.toString())
            }
    }


콘솔 창에서 필드 값을 변경해주면  변경 될때마다 아래와같이 이벤트가 발생하게 됩니다.


실행결과

I/System.out: UserDTO(name=범석, address=미국, age=null)
I/System.out: UserDTO(name=범석이, address=미국, age=null)
I/System.out: UserDTO(name=범석, address=미국, age=null)

I/System.out: UserDTO(name=범석, address=서울, age=null)


쿼리로 검색하게 될 경우를 보겠습니다.

Query로 검색을 할 경우 Paramater로 querySnapshot과 firebaseFirestoreException이 넘어옵니다.


우선 예를 확인하기전에 Firestore 에 document를 추가하겠습니다.


Document ID 는 Document2 필드는 name :범석 , address :광주 라고 입력하겠습니다.


실행 예)

private fun addSnapshotQuery(){
        firestore?.collection("User").whereEqualTo("name","범석")
            .addSnapshotListener { querySnapshot, firebaseFirestoreException ->
                for(dc in querySnapshot!!.documentChanges){
                    var document=dc.document.toObject(UserDTO::class.java)
                    println(document)
                }
            }
    }

범석이라는 name 필드를 가진 document를 처음모두 결과로 출력합니다.

그리고 그 document 값들이 변경될 때마다 데이터를 결과로 출력합니다.



결과값

I/System.out: UserDTO(name=범석, address=서울, age=null)
I/System.out: UserDTO(name=범석, address=광주, age=null)

I/System.out: UserDTO(name=범석, address=광진구, age=null)


댓글