How to read Data from Firebase in android studio using kotlin? - android

I want to get The name of the user and his email from the database, i use this to set the data to the database :
createUser
fun createUser( name:String, email: String, password: String) {
mProgressbar.setMessage("Please wait..")
mProgressbar.show()
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
val user = User(
name,
email
)
FirebaseDatabase.getInstance().getReference("Users")
.child(FirebaseAuth.getInstance().currentUser!!.uid)
.setValue(user).addOnCompleteListener(OnCompleteListener<Void> { task ->
if (task.isSuccessful) {
Toast.makeText(this, "Registered Successfully", Toast.LENGTH_LONG).show()
val Intent = Intent(applicationContext, MainActivity::class.java)
startActivity(Intent)
finish()
mProgressbar.dismiss()
} else {
//display a failure message
}
})
} else {
Toast.makeText(this, "Authentication failed.${task.exception}", Toast.LENGTH_SHORT).show()
mProgressbar.dismiss()
}
}
}
User
class User ( name: String, email: String) {
private var name: String? = name
private var email: String? = email
fun setName(Name: String) {
this.name = Name
}
fun getName(): String? {
return name
}
fun setEmail(Email: String) {
this.email = Email
}
fun getEmail(): String? {
return email
}
}
I need help please.I need help please.I need help please.I need help please.I need help please.I need help please.I need help please.I need help please.

internal var user: User? = null // declare user object outside onCreate Method
var ref = FirebaseDatabase.getInstance().getReference("Users").child(FirebaseAuth.getInstance().currentUser!!.uid)
val menuListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
user = dataSnapshot.getValue() as User
textView.text = user?.getName()
}
override fun onCancelled(databaseError: DatabaseError) {
// handle error
}
}
ref.addListenerForSingleValueEvent(menuListener)

The Code to get values from database
val menuListener = object : ValueEventListener {
override fun onCancelled(databaseError: DatabaseError) {
// handle error
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
user = dataSnapshot.getValue(User::class.java)
textView.text = user?.name
}
}
and i have to change User Class code to:
#IgnoreExtraProperties
data class User(
var name: String? = "",
var email: String? = ""
) {
#Exclude
fun toMap(): Map<String, Any?> {
return mapOf(
"uid" to name,
"author" to email
)
}
}

Related

Firebase Authentication is working but data is not storing in relatime database

My Authentication is working fine but I am not able to store and retrive data from realtime database. Below is the firebase rule(I am using locked mode and Usa server) and my signup Activity class. Please help me with this thing. I am taking database refernce and giving setValue method but still its not working. I have also tried different solution given on stackoverflow flow but still no luck.
Firebase Rule
{
"rules": {
".read": "true", // 2022-8-22
".write": "true"
}
}
SignUp Acitvity
class SignUpActivity : AppCompatActivity() {
private lateinit var mAuth : FirebaseAuth
private lateinit var mDBRef : DatabaseReference
private lateinit var binding: ActivitySignIntoBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySignIntoBinding.inflate(layoutInflater)
setContentView(binding.root)
mAuth = FirebaseAuth.getInstance()
binding.edtSignUp.setOnClickListener{
val name = binding.edtName.text.toString()
val email = binding.edtEmail.text.toString()
val password = binding.edtPassword.text.toString()
signUp(name, email, password)
}
binding.tvLogin.setOnClickListener {
val intent = Intent(this, Login::class.java)
finish()
startActivity(intent)
}
}
private fun signUp(name: String, email: String, password: String) {
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
addUserToDatabase(name, email, mAuth.currentUser?.uid!!)
val intent = Intent(this#SignUpActivity, MainActivity::class.java)
startActivity(intent)
} else {
Toast.makeText(this#SignUpActivity, "Some Error Occurred. Try Again", Toast.LENGTH_LONG ).show()
}
}
}
private fun addUserToDatabase(name: String, email: String, uid: String) {
mDBRef = FirebaseDatabase.getInstance("https://chatapplication-ad542-default-rtdb.firebaseio.com/").getReference()
mDBRef.child("User").child(uid).push().setValue(User(name, email, uid))
}
}

How we can link multiple authentication providers for phone and email in jetpack compose?

I have mail and mobile authentication in my register app, in firebase when user sign up with mail and mobile phone it generate two different UID for a same user, what I wish to achieve is one user with one UID can login with email or login by phone number (Merge the phone number and the email in authentication). May I possible to achieve this at Firebase? I have example here but I am not understand it how to implement to jetpack compose, any idea?
viewmodelphone:
#HiltViewModel
class AuthenticationViewModel #Inject constructor(
) : ViewModel() {
private val mAuth = FirebaseAuth.getInstance()
var verificationOtp = ""
var popNotification = mutableStateOf<Event<String>?>(null)
private lateinit var baseBuilder: PhoneAuthOptions.Builder
fun setActivity(activity: Activity) {
baseBuilder =
PhoneAuthOptions.newBuilder().setActivity(activity)
}
fun send(mobileNum: String) {
val options = baseBuilder
.setPhoneNumber("+91$mobileNum")
.setTimeout(60L, TimeUnit.SECONDS)
.setCallbacks(object :
PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
override fun onVerificationCompleted(p0: PhoneAuthCredential) {
handledException(customMessage = "Verification Completed")
}
override fun onVerificationFailed(p0: FirebaseException) {
handledException(customMessage = "Verification Failed")
}
override fun onCodeSent(otp: String, p1: PhoneAuthProvider.ForceResendingToken) {
super.onCodeSent(otp, p1)
verificationOtp = otp
handledException(customMessage = "Otp Send Successfully")
}
}).build()
PhoneAuthProvider.verifyPhoneNumber(options)
}
fun otpVerification(otp: String) {
val credential = PhoneAuthProvider.getCredential(verificationOtp, otp)
FirebaseAuth.getInstance().signInWithCredential(credential)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
handledException(customMessage = "Verification Successful")
} else {
handledException(customMessage = "Wrong Otp")
}
}
}
private fun handledException(exception: Exception? = null, customMessage: String = "") {
exception?.printStackTrace()
val errorMsg = exception?.message ?: ""
val message = if (customMessage.isEmpty()) {
errorMsg
} else {
"$customMessage: $errorMsg"
}
popNotification.value = Event(message)
}
}
I solve the problem when I add auth.currentUser?.linkWithCredential(credential) line of the code in otpVerification function.
fun otpVerification(otp: String) {
val credential = PhoneAuthProvider.getCredential(verificationOtp, otp)
auth.currentUser?.linkWithCredential(credential)
FirebaseAuth.getInstance().signInWithCredential(credential)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
handledException(customMessage = "Verification Successful")
} else {
handledException(customMessage = "Wrong Otp")
}
}
}

Data output from the FireBase database

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.
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.

User Data Not Saving To Firebase (Username, first name, Last Name)

I am trying to store data in my Firebase database but the app crashes when I call the function saveUserToFirebaseDatabase(). The performRegister() function works fine which stores the email and password using FirebaseAuth but when I call performRegister() then saveUserToFirebaseDatabase() right under it, the performRegister() doesn't execute all the way though. performRegister() is suppose to make a log.d tag which tells the uid and that it successfully stored the email and password. It does that but when I call saveUserToFirebaseDatabase() under performRegister() in the onCreate function, it doesn't log the uid like it did without the saveUserToFirebaseDatabase(). Instead the performRegister() Log displays the username and passowrd then skips to the saveUserToFirebaseDatabase() which logs display the username, first name, and last name from the previous activities the user had to enter when signing up for the account. Then it crashes. Here is my code. I want to be able to call performRegister() then saveUserToFirebaseDatabase() to save the user's email and password using FirebaseAuth then save the user's other information in the database using saveUserToFirebaseDatabase().
class Password_Activity : AppCompatActivity() {
lateinit var editPasswordText: EditText
lateinit var editConfirmPasswordText: EditText
lateinit var btnOpenActivity: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_password)
editPasswordText = findViewById(R.id.edit_password)
editConfirmPasswordText = findViewById(R.id.edit_confirm_password)
btnOpenActivity = findViewById(R.id.password_continue_btn)
// btnOpenActivity.isEnabled=false
val textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
var passwordinput: String = editPasswordText.text.toString().trim()
var confirmpasswordinput: String = editConfirmPasswordText.text.toString().trim()
btnOpenActivity.isEnabled = passwordinput.isNotEmpty() && confirmpasswordinput.isNotEmpty()
}
}
editPasswordText.addTextChangedListener(textWatcher)
editConfirmPasswordText.addTextChangedListener(textWatcher)
// var intent = intent
// val username = intent.getStringExtra("username")
// val firstname = intent.getStringExtra("firstname")
// val lastname = intent.getStringExtra("lastname")
// val emailaddress = intent.getStringExtra("emailaddress")
val btnOpenActivity: Button = findViewById(R.id.password_continue_btn)
btnOpenActivity.setOnClickListener {
performRegister()
saveUserToFirebaseDatabase()
// val intent = Intent(this, Main2Activity_welcome_after_signup_dashboard::class.java)
// startActivity(intent)
// overridePendingTransition(R.anim.slide_in_right,R.anim.slide_out_left)
}
}
// Save user's email and password
private fun performRegister(){
var intent = intent
val email = intent.getStringExtra("email")
val password = editPasswordText.text.toString().trim()
if (email.isEmpty() && password.isEmpty()) {
Toast.makeText(this, "Please enter email and password", Toast.LENGTH_SHORT).show()
return
}
Log.d("SignUpActivity","Email is "+ email)
Log.d("SignUpActivity","Password is $password")
// Initialize Firebase Auth
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (!it.isSuccessful) {
Log.d("SignUp", "Account creation unsuccessful")
return#addOnCompleteListener
}
//else if successful
Log.d("SignUp", "Successfully created user with uid: ${it.result?.user?.uid}")
}
.addOnFailureListener {
Log.d("SignUp", "Failed to create user: ${it.message}")
}
}
// Save user's username, first name, and last name to database
private fun saveUserToFirebaseDatabase(){
var intent = intent
val username = intent.getStringExtra("username")
val firstname = intent.getStringExtra("firstname")
val lastname = intent.getStringExtra("lastname")
Log.d("Signup","Storing user information in password activity: $username, $firstname, $lastname")
val uid = FirebaseAuth.getInstance().uid ?: ""
val ref = FirebaseDatabase.getInstance().getReference("/users/$uid")
val user = User(uid, username, firstname, lastname)
ref.setValue(user)
.addOnSuccessListener {
Log.d("Signup","We saved the user to Firebase Database")
}
.addOnFailureListener {
Log.d("Signup", "Failed to save user to Firebase Database")
return#addOnFailureListener
}
}
//Animation for back button
override fun finish() {
super.finish()
overridePendingTransition(R.anim.slide_in_left,R.anim.slide_out_right)
}
}
data class User(val uid: String, val username: String, val firstname: String, val lastname: String)
Your performRegister call happens aysnc in the background. This is why saveUserToFirebaseDatabase is getting called before it completes. Instead, just call it when performRegister is complete in the onCompleteListener.
Change this:
btnOpenActivity.setOnClickListener {
performRegister()
saveUserToFirebaseDatabase()
}
To:
btnOpenActivity.setOnClickListener {
performRegister()
}
and add saveUserToFirebaseDatabase() to:
.addOnCompleteListener {
if (!it.isSuccessful) {
Log.d("SignUp", "Account creation unsuccessful")
return#addOnCompleteListener
}
//else if successful
saveUserToFirebaseDatabase()
Log.d("SignUp", "Successfully created user with uid: ${it.result?.user?.uid}")
}

Display target data from firebase

I display a list of my targets in fragmentA, when I click on one of them, I pass the guid of this target to the fragmentB
After that, I try in the fragmentB display the data of this target for this guid:
private fun fetchTarget(guid: String) {
val uid = firebaseUser!!.uid
// Attach a listener to read the data at the target id
databaseReference?.child("targets")?.child("users")
?.child(uid)?.child("targets")?.child(guid)?.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val data = dataSnapshot.value as? HashMap<String, String>?
val name = data?.get("name") ?: ""
val description = data?.get("description") ?: ""
if (name.isEmpty()) Log.d("some", "nameIsEmpty")
else updateViewsContent(name = name, description = description)
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("some", databaseError.message)
}
})
}
Here I get the guid: -LmfEVnwgqCUqt7beHDg
And in my console i have next structure:
Unfortunately I can't display data of target, though like all the chains I installed
Q: How i can download -LmfEVnx-y7c3oh8_U9F ?
To display the data that belongs to a single guid, you should use a query and then iterate through the DataSnapshot object like in the following lines of code:
val uid = FirebaseAuth.getInstance().currentUser!!.uid
val rootRef = FirebaseDatabase.getInstance().reference
val targetsRef = rootRef!!.child("targets").child("users").child(uid).child("targets")
val query = targetsRef.orderByChild("guid").equalTo("-LmfEVnwgqCUqt7beHDg")
val valueEventListener = object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
for (ds in dataSnapshot.children) {
val target = ds.getValue(Target::class.java)
Log.d(TAG, target.name)
}
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d(TAG, databaseError.getMessage()) //Don't ignore errors!
}
}
query.addListenerForSingleValueEvent(valueEventListener)
The result in the logcat will be:
fgg
You are not getting any data because to get above data your guid value in query should be "-LmfEVnx-y7c3oh8_U9F" but you are passing "-LmfEVnwgqCUqt7beHDg".
You can try below query to get above data:
val uid = firebaseUser!!.uid
// Attach a listener to read the data at the target id
databaseReference?.child("targets")?.child("users")?.child(uid)?.child("targets")?.orderByChild("guid").equalTo(guid)?.addValueEventListener(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val data = dataSnapshot.value as? HashMap<String, String>?
val name = data?.get("name") ?: ""
val description = data?.get("description") ?: ""
if (name.isEmpty()) Log.d("some", "nameIsEmpty")
else updateViewsContent(name = name, description = description)
}
override fun onCancelled(databaseError: DatabaseError) {
Log.d("some", databaseError.message)
}
})

Categories

Resources