0

I am working on an android app and using Kotlin for the first time. The program does the following:

1) Login

2) Write Data to Database (Firebase Realtime Database)

3) Read Data from Database (RecycleView + Adapter with ViewHolder)

4) Users: Normal, Admin, Special

"Normal" users can input data and look at database objects using RecycleView + ViewHolder; "Admin" can overwrite a specific identifier in objects in the database by clicking a button (which is invisible for other users); "Special" users can only see those objects with that specific identifier in them using RecycleView + ViewHolder.

The problem is: specific RecycleView for "Special" users doesn't work. The Activity just crashes. The Adapter for RecycleView works: data is submitted to the database by "normal" users and data is displayed correctly in TextView + ViewHolder, even after updating through Admin user.

Here is my code (### represent hashes that are hardcoded for testing purposes):

class SchadenAdapter : RecyclerView.Adapter<SchadenViewHolder>() {
[...]
class SchadenViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(schaden: Schaden) {

    val userId: String = FirebaseAuth.getInstance().currentUser!!.uid

    itemView.textViewSchadenort.text = schaden.schadenort
    itemView.textViewSchadenart.text = schaden.schadenart
    itemView.textViewSchadendatum.text = schaden.datum
    itemView.textViewSchadenstatus.text = schaden.status

    if (userId == "###") {
        itemView.buttonTextViewAllocate.setOnClickListener() {
            (R.layout.item_schaden)
            // show message box after button click
            AlertDialog.Builder(itemView.context)
                .setMessage("Schaden zugeteilt.")
                .create()
                .show()
            // get uuid: update "allocate" + "status"
            val rootRef = FirebaseDatabase.getInstance().reference
            val uuidRef = schaden.uuid
            rootRef.child("schäden")
                .child(uuidRef)
                .child("allocated")
                .setValue("###")
            rootRef.child("schäden")
                .child(uuidRef)
                .child("status")
                .setValue("###")
        }
    } else {
        itemView.buttonTextViewAllocate.setVisibility(View.GONE)
    }
}
}

At first I tried to do the same for "Special" users: I created a button in the layout.xml and just used the same structure in the Adapter - the only difference is that they can only change "status" by clicking a button. But everytime I tried to do so, the app crashed.

For the sake of completeness, here is the code for the Activity that uses the Adapter:

class SchadenListeActivity : AppCompatActivity() {

private lateinit var databaseReference: DatabaseReference
private lateinit var schadenAdapter: SchadenAdapter

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

    databaseReference = FirebaseDatabase.getInstance().reference
    schadenAdapter = SchadenAdapter()

    recyclerViewSchadenliste.layoutManager = LinearLayoutManager(this)
    recyclerViewSchadenliste.adapter = schadenAdapter
    val itemDecor = DividerItemDecoration(this, VERTICAL)
    recyclerViewSchadenliste.addItemDecoration(itemDecor)

    databaseReference.child("schäden")
        .addValueEventListener(object : ValueEventListener {
        override fun onCancelled(databaseError: DatabaseError) {
            Toast.makeText(this@SchadenListeActivity,
                "Database error: $databaseError.message", Toast.LENGTH_SHORT).show()
        }

        override fun onDataChange(dataSnapshot: DataSnapshot) {
            val schadenListe = dataSnapshot.children.mapNotNull { it.getValue<Schaden>(Schaden::class.java) }
            schadenAdapter.setSchaden(schadenListe)
        }
    })
}
}

Help is greatly appreciated.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
MichaelP
  • 41
  • 10
  • 3
    If the app crashes, there is a stack trace. Please look that up on logcat, and add it to your question. – Alex Mamo Jan 12 '20 at 05:14
  • Possible duplicate: [How to create RecyclerView with multiple view type?](https://stackoverflow.com/questions/26245139/how-to-create-recyclerview-with-multiple-view-type) – Martin Zeitler Jan 12 '20 at 07:05
  • Martin Zeiler my question is not a duplicate to the question you posted. I am not trying to get multiple view types into one recycler view. I am just trying to create different event view holders so that I can use one recycler view but get different output for different user roles. – MichaelP Jan 17 '20 at 14:24
  • Alex Mamo thank you for the advice. I found the problem: I had copied and pasted the code from one event view holder but forgotten to change the name of the button. So it was a typo. It now works. Thank you. – MichaelP Jan 17 '20 at 14:26

1 Answers1

0

I am not exactly sure of the app crash, what I can observe seeing your code is your are trying to show alert dialog using itemView.context which is not possible. You can show a dialog using activity context only. Try to show the dialog using activity context and check if its still crashing.

Please provide the stacktrace of your current app crash.

Prashant Jha
  • 574
  • 6
  • 21
  • 1
    Thank you but the alert works. The problem was a typo. I copied and pasted code from the first part and forgot to adapt it to the ID of the other button. Must have been getting too little sleep. But thank you for your input. – MichaelP Jan 17 '20 at 14:28