Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a document contents from Firestore by custom object? (Android - Kotlin)

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()
        }


}    
like image 212
Ali Almesbah Avatar asked Nov 07 '22 22:11

Ali Almesbah


1 Answers

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.

like image 183
Doug Stevenson Avatar answered Nov 14 '22 10:11

Doug Stevenson