I'm trying to get a document contents from Firestore. The following image link shows the database structure Firestore database structure
What I want: I want to get a document contents by a custom object and add the contents to a list.
The problem: I'm getting this error: E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.aalmesbah.turoodpilot, PID: 12160 java.lang.RuntimeException: Could not deserialize object. Class com.google.firebase.auth.UserInfo does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped
I tried to get the document content by get() and getString() methods and it worked fine the problem is only with the toObject()?
I've searched and tried some suggested solutions from other questions here like add default values for the data class, but it didn't work, unfortunately.
data class code:
data class UserInfo (val name: String? = "",
val email: String? = "",
val phoneNum: String? = "",
val address: String? = "") {
constructor(): this("","","", "" )
}
Profile Fragment code: (where the document contents suppose to be shown)
class ProfileFragment : Fragment() {
private lateinit var auth: FirebaseAuth
private lateinit var db: FirebaseFirestore
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_profile, container, false)
auth = FirebaseAuth.getInstance()
db = FirebaseFirestore.getInstance()
return view
}
override fun onStart() {
super.onStart()
val userID = auth.currentUser?.uid
val docRef = db.collection("users").document(userID!!)
docRef.addSnapshotListener(EventListener<DocumentSnapshot> { documentSnapshot, e ->
if (e != null) {
Log.w(TAG, "Listen failed.", e)
return@EventListener
}
if (documentSnapshot != null && documentSnapshot.exists()) {
docRef.get().addOnSuccessListener { documentSnapshot ->
val userInfo = documentSnapshot.toObject(UserInfo::class.java)
emailTV.text = userInfo?.email
}
} else {
Log.d(TAG, "Current data: null")
}
})
}
}
sendUserData() method code at Registration activity
private fun sendUserData() {
val name = userN.text.toString()
val email = userEm.text.toString()
val phone = userPhone.text.toString()
val addressName = addressName.text.toString()
val area = area.text.toString()
val block = block.text.toString()
val street = strees.text.toString()
val avenue = avenue.text.toString()
val house = house.text.toString()
val floor = floor.text.toString()
val apartment = apartment.text.toString()
val additionalInfo = additional.text.toString()
val address = "Addres Name: $addressName \n Area: $area \n B: $block ST: $street Av: $avenue H: $house\n " +
"Floor: $floor Apartment: $apartment \n Notes: $additionalInfo"
val userID = auth.currentUser?.uid
val userData = UserInfo(name, email, phone, address)
db.collection("users").document(userID!!).set(userData).addOnSuccessListener {
Toast.makeText(this, "Successfully Registered", Toast.LENGTH_SHORT).show()
}.addOnFailureListener{
Toast.makeText(this, "Data Upload error!", Toast.LENGTH_SHORT).show()
}
}
If you want to use a Kotlin data class with documentSnapshot.toObject
, you're going to have to make each field a nullable var
instead of val
. The Firestore SDK doesn't know how to map document fields into data class constructor argument.
If you want a proper immutable data class with val
fields, you're going to have to manually read each field out of the document, and call the data class constructor yourself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With