0

I am new to kotlin. And so I need help. Thank. I have a date class Users ().

data class Users(
var ID: String = "",
var Email: String = "")

Date class I fill through initUser

lateinit var AUTH: FirebaseAuth
lateinit var UID:String
lateinit var REF_DATABASE_ROOT: DatabaseReference
lateinit var USER:Users

const val NODE_USERS = "User"
const val CHILD_ID = "ID"
const val CHILD_EMAIL = "Email"


fun initFirebase() {
    AUTH = FirebaseAuth.getInstance()
    REF_DATABASE_ROOT = FirebaseDatabase.getInstance().reference
    UID = AUTH.currentUser?.uid.toString()
    USER = Users()
}

fun initUser() {
    REF_DATABASE_ROOT.child(NODE_USERS).child(UID)
        .addValueEventListener(object : ValueEventListener {
            override fun onCancelled(p0: DatabaseError) {}
            override fun onDataChange(p0: DataSnapshot) {
                USER = p0.getValue(Users::class.java) ?:Users()
            }
        })
}

But when I want to display the user's email from the database via text. I get the void

initFirebase()
initUser()
textViewMain.text = USER.Email.toString()

Here is new JSON:

{
  "User" : {
    "ZDLM84F7zYWobbhUBxsQfekrPvI3" : {
      "Email" : "evgeniy1900@gmail.com",
      "ID" : "ZDLM84F7zYWobbhUBxsQfekrPvI3"
    }
  }
}

But again I get nothing in text

UPDATE:

Ok, I wrote it all over again. And now I have: Data class User

import com.google.firebase.database.PropertyName

data class User (
    @PropertyName("id")
    var id: String = "",
    @PropertyName("email")
    var email: String = ""
)

initUser looks like that

lateinit var AUTH: FirebaseAuth
lateinit var UID:String
lateinit var REF_DATABASE_ROOT: DatabaseReference
lateinit var USER:User

const val NODE_USERS = "users"
const val CHILD_ID = "id"
const val CHILD_EMAIL = "email"

fun initFirebase() {
    AUTH = FirebaseAuth.getInstance()
    REF_DATABASE_ROOT = FirebaseDatabase.getInstance().reference
    UID = AUTH.currentUser?.uid.toString()
    USER = User()
}
fun initUser() {
    REF_DATABASE_ROOT.child(NODE_USERS).child(UID)
        .addListenerForSingleValueEvent(AppValueEventListener{
          USER = it.getValue(User::class.java) ?:User()
        })
}

and also I decided to shorten the code using AppValueEventListener here he is

class AppValueEventListener (val onSuccess:(DataSnapshot) -> Unit) :ValueEventListener{
    override fun onCancelled(p0: DatabaseError) {}
    override fun onDataChange(p0: DataSnapshot) { onSuccess(p0) }
}

and this is json

{
  "users" : {
    "ZDLM84F7zYWobbhUBxsQfekrPvI3" : {
      "email" : "evgeniy1900@gmail.com",
      "id" : "ZDLM84F7zYWobbhUBxsQfekrPvI3"
    }
  }
}

As you can see, I added @PropertyName ("email"). But at the same time, I still do not get anything on the screen. enter image description here

Update again:

I used a breakpoint in order to understand if I am getting something from the database or not. As you can see in the screenshots, there is a receipt, but there is no record in the User model. Help me please.

enter image description here

enter image description here

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
lUjekSh
  • 65
  • 1
  • 1
  • 8
  • Can you edit your question to include the JSON at `/NODE_USERS/$UID` in your database (as text, no screenshots please). You can get this by clicking the "Export JSON" link in the overflow menu (⠇) on your [Firebase Database console](https://console.firebase.google.com/project/_/database/data). – Frank van Puffelen Jun 28 '20 at 16:38
  • If you `console.log(UID)` right before `REF_DATABASE_ROOT.child(NODE_USERS).child(UID).addListenerForSingleValueEvent(...` what does it print? – Frank van Puffelen Jun 29 '20 at 00:23
  • 1
    I/System.out: ZDLM84F7zYWobbhUBxsQfekrPvI3 – lUjekSh Jun 29 '20 at 00:34
  • The breakpoint in that last screenshot is in a place where `USER` is unlikely to have the correct value. Any code that needs data from the database should be *inside* the `onDataChange` that is called for that data. Also see https://stackoverflow.com/questions/50434836/getcontactsfromfirebase-method-return-an-empty-list/50435519#50435519. – Frank van Puffelen Jun 29 '20 at 03:47
  • Thanks, it works. You helped me a lot. – lUjekSh Jun 29 '20 at 09:49
  • Btw: please don't leave `onCancelled` empty, as you're hiding potential errors. At the very least it should be `override fun onCancelled(error: DatabaseError) { throw error.toException(); }` – Frank van Puffelen Jul 11 '20 at 23:59

1 Answers1

0

Your JSON contains this property for a user:

"EMAIL" : "evgeniy1900@gmail.com",

Which you likely want to map to this in your code:

var Email: String = ""

But Firebase uses JavaBean naming conventions when mapping, which means that your JSON actually maps to a property in Kotlin as:

var eMAIL: String = ""

If you want to maintain both the name on JSON and in Kotlin, you can use a PropertyName annotation:

@PropertyName("EMAIL")
var Email: String = ""

Also see: Firebase @PropertyName doesn't work and probably others from this search.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Not work. Even when the EMAIL base was written in the same way as in the data class Users. Nothing worked anyway. – lUjekSh Jun 28 '20 at 18:07
  • My FireBase new JSON: { "User" : { "ZDLM84F7zYWobbhUBxsQfekrPvI3" : { "Email" : "evgeniy1900@gmail.com", "ID" : "ZDLM84F7zYWobbhUBxsQfekrPvI3" } } } But again I get nothing in text – lUjekSh Jun 28 '20 at 18:17
  • Even in your updated data class the `var Email: String = ""` maps to a database property `email`, which is not what you have in your JSON. – Frank van Puffelen Jun 28 '20 at 19:21