본문 바로가기
내일배움캠프 (스파르타 코딩 클럽) 안드로이드 2기/TIL

코틀린| MVVM & 파이어스토어 데이터베이스에서 데이터 가져오기

by 키윤 2024. 3. 6.

MVVM 패턴은 뷰 - 뷰모델 - 모델 - 디비

순으로 연결이 되기 때문에

리포지토리에서 파이어스토어 디비랑 연결을 해주었다.

// Repository.kt

class Repository {
    private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
    
    init {
        Log.d(TAG, "init 함수")
        initPush(0)
    }

	fun initPush(index: Int) {

        Log.d(TAG, "initPush 함수 여기에서 데이터베이스에 있는 값 접근")
        val sanArrayList: ArrayList<SanDTO> = arrayListOf()

        db.collection("sanlist").get().addOnSuccessListener { documents ->


            for (i in documents.documents.indices) {
                val sanInfo = documents.documents[i]

                sanArrayList.add(
                    SanDTO(
                        sanImage = sanInfo["images"] as ArrayList<String>,
                        sanName = sanInfo["name"] as String,
                        sanDifficulty = sanInfo["difficulty"] as Long?,
                        sanHeight = sanInfo.getLong("height") ?: 0,
                        sanTimeTotal = (sanInfo["time_uphill"] as Long) + (sanInfo["time_downhill"] as Long),
                        sanSelected = false
                    )
                )

            }
            
        }

 

데이터 베이스에서 가져온 데이터들을 적절하게 처리하여 내가 사용할 SanDTO에 수정하여 넣어주었다.

데이터베이스에서 데이터를 가져오는 방법에는 여러가지 방법이 있다. 나는 지금 위에서 보이듣싱 addOnSuccessListener 함수를 사용하여 데이터를 가져온다. 이 함수가 호출 될때마다 데이터가 업데이트 된다고 볼 수 있다. 반면에 이 함수 대신에 addOnSnapShotListener을 사용하면 실시간으로 데이터가 동기화 시킬 수 있다. 하지만 나는 지금 저장되어있는 산 정보 목록을 가져오는 것이기 때문에 실시간 업데이트를 필요로 하지 않아서 addOnSuccessListener을 통해 구현을 했다. 만약 실시간 업데이트를 필요로 하면 addOnSuccessListener을 사용하면 될 것 같다.

데이터를 가져올 때 유의해야하는 점이 타입을 정확하게 해줘야한다.. 안그러면 오류..ㄷ

DTO는 Data Transfer Object라고 데이터를 변환시킬때 사용해주는 객체라고 한다. DAO(Data Access Object)를 룸디비에서 사용했었는데 이 객체는 데이터를 처리해주고 변환시켜주는 역할을 하기 때문에 dto를 붙여 보았다. 물론 간지나기 때문도 있다.

viewmodel:

private const val TAG = "SanListViewModel"

class SanListViewModel(sanListRepository: SanListRepository) : ViewModel() {

    private val repository : SanListRepository = sanListRepository
    private var _sanListUiState = MutableLiveData<SanListUiState?>()

    val sanListUiState: LiveData<SanListUiState?> = _sanListUiState

    val sanList: LiveData<List<SanDTO>> = repository.sanListDTO



    init {
        _sanListUiState.value = SanListUiState.init()
    }

    fun getSelectedItem(item: SanDTO?) {
        Log.d(TAG, "getSelectedItem ${item.toString()}")
        if (item == null) {
            Log.d(TAG, "널값 넘어옴")

        } else {
            _sanListUiState.value = sanListUiState.value?.copy(selectedItem = item)
            Log.d(TAG, _sanListUiState.value.toString())




        }
    }

    fun setInitiallySelectedItem() {
        _sanListUiState.value = sanListUiState.value?.copy(
            selectedItem = sanList.value?.get(0)
        )
    }


    fun updateSelectedItemOnDTO(item: SanDTO) {
        repository.editSelectedItem(item)
    }
}