1

I am a new about Android Kotlin. I try to delete the data from Cloud Firebase when I click the button on my app. I did some necessary code on my adapter but How can ı call the database collection on my Activity? ı shared the my adapter and my Activity code below.

class NoteAdapter(val titleText: ArrayList<String>, val rowImage: ArrayList<String>, val noteText: ArrayList<String>, val listener: onClick) : RecyclerView.Adapter<NoteAdapter.NoteHolder>() {


    interface onClick {

        fun onItemClickListener(v: View, pos: Int, data: Any)


    }


    class NoteHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val itemImage : ImageView = itemView.findViewById(R.id.recyclerImage)
        val itemDelete: ImageView = itemView.findViewById(R.id.delete)


    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteHolder {

        val v = LayoutInflater.from(parent.context).inflate(R.layout.recycler_row, parent, false)
        return NoteHolder(v)
    }

    override fun onBindViewHolder(holder: NoteHolder, position: Int) {

        holder.itemView.recyclerTitleText.text = titleText[position]
        Picasso.get().load(rowImage[position]).resize(150,150).into(holder.itemImage)

        holder.itemView.setOnClickListener {


            val intent = Intent(holder.itemView.context, PastNotesActivity:: class.java)
            intent.putExtra("oldTitle", titleText[position])
            intent.putExtra("oldNote", noteText[position])
            intent.putExtra("oldImage", rowImage[position])
            holder.itemView.context.startActivity(intent)


        }

        holder.itemDelete.setOnClickListener { v: View ->

            titleText.removeAt(position)
            noteText.removeAt(position)
            rowImage.removeAt(position)

            notifyItemRemoved(position)

            listener.onItemClickListener(v, position, holder.itemView)
        }

    }

    override fun getItemCount(): Int {

        return titleText.size
    }


    override fun getItemId(position: Int):Long  {
        return position.toLong()
    }

    override fun getItemViewType(position: Int):Int {
        return position
    }


}

And This is my Activity code, I create the itemDelete fun in this Activity but How can I define my adapter code in this fun? and I tried to write "{id.data}" in my document but did not work what should I write ?

class ListViewActivity : AppCompatActivity() {

    var selectedPicture: Uri? = null

    private  lateinit var auth: FirebaseAuth
    private lateinit var db : FirebaseFirestore

    var titleTextFromFB : ArrayList<String> = ArrayList()
    var noteTextFromFB : ArrayList<String> = ArrayList()
    var imageFromFB : ArrayList<String> = ArrayList()


    var adapter: NoteAdapter? = null



    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_list_view)

        auth = FirebaseAuth.getInstance()
        db = FirebaseFirestore.getInstance()

        getDataFromFirestore()

        // recyclerview

        var layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager

       // adapter = NoteAdapter(titleTextFromFB, imageFromFB, noteTextFromFB)
        //recyclerView.adapter = adapter

        adapter = NoteAdapter(titleTextFromFB, imageFromFB, noteTextFromFB, object: NoteAdapter.onClick{

            override fun onItemClickListener(v: View, pos: Int, data: Any) {

                when(v.id){

                    R.id.delete -> itemDelete(data)

                }

            }

        })

        recyclerView.adapter = adapter

    }


    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        val menuInflater = menuInflater
        menuInflater.inflate(R.menu.add_note, menu)

        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        if (item.itemId == R.id.add_note_click) {
            // Take Notes Activity
            val intent = Intent(applicationContext, TakeNotesActivity::class.java)
            intent.putExtra("info","new")
            startActivity(intent)

        } else if (item.itemId == R.id.log_out) {

            val alert = AlertDialog.Builder(this)

            alert.setTitle("Log Out")
            alert.setMessage("Are you sure to logout from the app ?")
            alert.setPositiveButton("Yes") {dialog, which ->

                auth.signOut()
                val intent = Intent(applicationContext, MainActivity::class.java)
                startActivity(intent)
                finish()
            }

            alert.setNegativeButton("No") {dialog, which ->

            }

            alert.show()

        }

        return super.onOptionsItemSelected(item)
    }

    // get data from firestore

    fun getDataFromFirestore() {

        db.collection("Notes").orderBy("date", Query.Direction.DESCENDING).addSnapshotListener{ snapshot, exception ->

            if (exception != null) {

                // If there is a error ,

                Toast.makeText(applicationContext, exception.localizedMessage.toString(), Toast.LENGTH_LONG).show()

            } else {

                if (snapshot != null) {

                    if (!snapshot.isEmpty) {

                        titleTextFromFB.clear()
                        noteTextFromFB.clear()
                        imageFromFB.clear()

                        val documents = snapshot.documents
                        for (document in documents) {

                            val userEmail = document.get("userEmail") as String
                            val noteTitle = document.get("noteTitle") as String
                            val yourNote = document.get("yourNote") as String
                            val downloadUrl = document.get("downloadUrl") as String
                            val timestamp = document.get("date") as Timestamp
                            val date = timestamp.toDate()

                            titleTextFromFB.add(noteTitle)
                            imageFromFB.add(downloadUrl)
                            noteTextFromFB.add(yourNote)

                            adapter!!.notifyDataSetChanged()

                        }
                    }
                }

            }


        }


    }

    fun itemDelete(data: Any) {

        db.collection("Notes").document().delete().addOnSuccessListener {


        }

            .addOnFailureListener { exception ->

                Toast.makeText(applicationContext, exception.localizedMessage.toString(), Toast.LENGTH_LONG).show()
            }
    }


}
ibrmrt
  • 57
  • 2
  • 8
  • what do you mean by "How can ı call the database collection in this fun"? i mean you are already calling database collection for deletion – Ali Oct 15 '20 at 11:34
  • Yes I already called it but What should I write in the document and how can I defined my adapter in this fun . I tried to write like this but did not work; db.collection("Notes").document("{data.id}").delete().addOnSuccessListener { } – ibrmrt Oct 15 '20 at 11:38
  • [This should be of some help Please let me know if it actually worked for you](https://stackoverflow.com/a/37393676/13167993) – Nitin Tej Oct 15 '20 at 11:44
  • are you trying to say that how to update the adapter when the item is successfully deleted? – Ali Oct 15 '20 at 12:08
  • Yes and also What should I write in my document() code ? I editted the description. It is more clear now – ibrmrt Oct 15 '20 at 12:13

1 Answers1

2

This code won't work:

   db.collection("Notes").document().delete().addOnSuccessListener {

The db.collection("Notes").document() call creates a reference to a new document, which you then delete. So nothing happens.

What you need to do is determine the ID of the document that the user clicked on, and pass that into the document(...) call. That gives you a DocumentReference to the correct document, so that the delete() call will then delete that document.

The key to determining the ID of the document the user clicked on is in this code:

adapter = NoteAdapter(titleTextFromFB, imageFromFB, noteTextFromFB, object: NoteAdapter.onClick{
    override fun onItemClickListener(v: View, pos: Int, data: Any) {
        when(v.id){
            R.id.delete -> itemDelete(data)
        }
    }
})

You will need to determine the ID from one of these parameters: v, post, or data. I typically do this by keeping a list of document IDs or DocumentSnapshot objects in my adapter or activity, and then looking the clicked item up by its position/index.

So in your getDataFromFirestore function, add the snapshots to a list that you've defined as a field in your activity class:

// in your activity, declare a list;
var mDocuments: List<DocumentSnapshot>? = null

// Then in getDataFromFirestore store that list
...
mDocuments = snapshot.documents;
val documents = snapshot.documents
for (document in documents) {
    ...
}
...

// And use it when calling itemDelete:
adapter = NoteAdapter(titleTextFromFB, imageFromFB, noteTextFromFB, object: NoteAdapter.onClick{
    override fun onItemClickListener(v: View, pos: Int, data: Any) {
        when(v.id){
            R.id.delete -> itemDelete(mDocuments[pos])
        }
    }
})

// To then finally delete the document by its ID
fun itemDelete(doc: DocumentSnapshot) {
    db.collection("Notes").document(doc.Id).delete()
}

ibrmrt
  • 57
  • 2
  • 8
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807