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.