[안드로이드] firebase cloud firestore 사용하기 - Todolist 앱

나고수·2021년 10월 19일
0

andriod

목록 보기
23/27

github에서 전체 코드 보기
Todolist 앱 만들기 중 firebase cloud firestore 사용하기 부분만 발췌했습니다.

class MyViewModel : ViewModel() {
    val liveTodoData = MutableLiveData<List<DocumentSnapshot>>()
    //firebase의 firestore 가져오기
    val db = Firebase.firestore
    // 현재 유저의 아이디 (로 컬렉션을 만들었음)
    val userid = FirebaseAuth.getInstance().currentUser?.uid
    
    init {
        reload()
    }
    //firestore에 저장된 데이터 불러오기
    fun reload() {
        //db.collection(컬렉션이름. 여기서는 userid)
        db.collection(userid.toString()) 
            //실시간으로 데이터가져오기
            //데이터를 실시간으로 가져오기 때문에 
           //데이터 삭제, 수정, 추가 한 후 데이터를 다시 받아오지 않아도 됨
            .addSnapshotListener { result, e ->
                if (e != null) {
                    return@addSnapshotListener
                }
		//가져온 결과를 라이브데이터에 넣기
                liveTodoData.value = result?.documents
            }
    }
    //일정 추가 - document 추가 
    fun addTodo(todo: Todo) {
        db.collection(userid.toString()).add(todo)
    }
    //일정 삭제 - 특정 document 삭제
    fun deleteTodo(todo: DocumentSnapshot) {
  db.collection(userid.toString()).document(todo.id).delete()
    }
    //할일 완료 - 필드 업데이트
    fun doneTodo(todo: DocumentSnapshot) {
        val isDone = todo.getBoolean("isDone") ?: false
        db.collection(userid.toString()).document(todo.id).update("isDone", !isDone)
    }
}
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    //뷰모델 가져오기
    val model: MyViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        //리사이클러뷰 만들기
        binding.recyclerView.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter =
                TodoAdapter(
                    layoutInflater,
                    emptyList(),
                    onClickDeleteIcon = {
                        model.deleteTodo(it)
                    },
                    onClickDoneIcon = {
                        model.doneTodo(it)
                    })
        }
        //일정 추가 버튼
        binding.btnAdd.setOnClickListener {
            model.addTodo(Todo(binding.editText.text.toString()))
        }

        //mutablelivedata 바뀔때마다 adapter에 list 업데이트해주기
        model.liveTodoData.observe(this, Observer {
            (binding.recyclerView.adapter as TodoAdapter).setData(it)
        })
    }
}

data class Todo(val text: String, var isDone: Boolean = false)
class TodoAdapter(
    val inflater: LayoutInflater,
    var list: List<DocumentSnapshot>,
    val onClickDeleteIcon: (todo: DocumentSnapshot) -> Unit, 
    val onClickDoneIcon: (todo: DocumentSnapshot) -> Unit
) :
    RecyclerView.Adapter<TodoAdapter.TodoViewHolder>() {
    inner class TodoViewHolder(val binding: ItemTodoBinding) :
        RecyclerView.ViewHolder(binding.root) {
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
        val view = inflater.inflate(R.layout.item_todo, parent, false)
        return TodoViewHolder(ItemTodoBinding.bind(view))
    }

    override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
        holder.binding.txtTodo.text = list[position].getString("text")

        //작업 완료 일때 글자체 처리
        if (list[position].getBoolean("isDone") == true) {
            holder.binding.txtTodo.apply {
                paintFlags = paintFlags or Paint.STRIKE_THRU_TEXT_FLAG //3. 삭선넣기 & 이탤릭체
                setTypeface(null, Typeface.ITALIC)
            }
        } else {
            holder.binding.txtTodo.apply {
                paintFlags = 0
                setTypeface(null, Typeface.NORMAL)
            }
        }
        //할일 완료 처리 
        holder.binding.txtTodo.setOnClickListener {
            onClickDoneIcon.invoke(list[position])
        }

        //삭제처리
        holder.binding.imgDelete.setOnClickListener {
            onClickDeleteIcon.invoke(list[position])
        }
    }

    override fun getItemCount(): Int {
        return list.size
    }
    //livedata가 바뀔때마다 adapter의 list를 업데이트해주고
    //recyclerview를 다시 그린다.
    fun setData(new: List<DocumentSnapshot>) {
        list = new
        notifyDataSetChanged()
    }
}
profile
되고싶다

1개의 댓글

comment-user-thumbnail
2022년 6월 15일

안녕하세요 혹시
//한번만 가져오기
// .get() //컬렉션 가져오기
// .addOnSuccessListener { result ->
// for (document in result) {
// val todo =
// Todo(document.data["text"] as String, document.data["isDone"] as Boolean)
// datalist.add(todo)
// }
// liveTodoData.value = datalist
// }
// .addOnFailureListener { e ->
// }
이 부분에서 전부 똑같이 했는데 datalist.add(todo)에서 에러가 뜨는데 datalist에 add함수가 없다는 에러가 발생합니다. 혹시 다르게 할 수 있는 방법이 있을까요?

답글 달기