This question already has answers here:
Firebase Realtime Database connection killed: Different Region
(5 answers)
Closed 9 months ago.
I am making a Tinderr clone and i want to store the users in the realtime database of Firebase. I have followed the documentation and multiple youtube vids but nothing works. The users do get stored in the authentication so why not in the database?
SignupActivity :
package com.example.dogsharev2.activities
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import com.example.dogsharev2.R
import com.example.dogsharev2.util.DATA_USERS
import com.example.dogsharev2.util.User
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import kotlinx.android.synthetic.main.activity_signup.*
class SignupActivity : AppCompatActivity() {
private val firebaseDatabase = FirebaseDatabase.getInstance().reference
private val firebaseAuth = FirebaseAuth.getInstance()
private val firebaseAuthListener = FirebaseAuth.AuthStateListener {
val user = firebaseAuth.currentUser
if(user != null) {
startActivity(MainActivity.newIntent(this))
finish()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_signup)
}
override fun onStart() {
super.onStart()
firebaseAuth.addAuthStateListener(firebaseAuthListener)
}
override fun onStop() {
super.onStop()
firebaseAuth.removeAuthStateListener(firebaseAuthListener)
}
fun onSignup(v: View) {
if(!emailET.text.toString().isNullOrEmpty() && !passwordET.text.toString().isNullOrEmpty()) {
firebaseAuth.createUserWithEmailAndPassword(emailET.text.toString(), passwordET.text.toString())
.addOnCompleteListener { task ->
if(!task.isSuccessful) {
Toast.makeText(this, "Signup error ${task.exception?.localizedMessage}", Toast.LENGTH_SHORT).show()
} else {
val email = emailET.text.toString()
val userId = firebaseAuth.currentUser?.uid ?: ""
val user = User(userId, "", "", email, "", "", "")
firebaseDatabase.child(DATA_USERS).child(userId).setValue(user)
}
}
}
}
companion object {
fun newIntent(context: Context?) = Intent(context, SignupActivity::class.java)
}
}
Data.kt
package com.example.dogsharev2.util
data class User(
val uid: String? = "",
val name: String? = "",
val age: String? = "",
val email: String? = "",
val gender: String? = "",
val preferredGender: String? = "",
val imageUrl: String? = ""
)
Constabts.kt
ackage com.example.dogsharev2.util
val DATA_USERS = "Users"
I have implemented 'com.google.firebase:firebase-database-ktx:20.0.5' also. And set the rules of my database to true.
Thanks in advance
I have analyzed it multiple times and everything seems perfectly fine. What you can do is to add a listener to setValue(user) method like this:
firebaseDatabase.child(DATA_USERS).child(userId).setValue(user)
.addOnCompleteListener { task ->
if(task.isSuccessful) {
Toast.makeText(this, "Successful", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, task.getException().getMessage(),
Toast.LENGTH_SHORT).show();
}
}
Now task.getException().getMessage() will let you know what the actual problem is about saving your user data.
Related
I hope you are all doing well.
I have run into a few problems and can't seem to find the answer online in an applicable way to my scenario. I am coding in Kotlin.
My database resides on an external host but I have already got the database connection set up and connected.
I have a login activity with a username and password field, and a login button. I have managed to verify the login details by setting specific credentials but I now have a database, SQL, linked to my android app. How do I verify the login credentials the user input against the database and check if the user is active?
Name: Bobby
Database Host: sql99.dbn7.host-h.net
Database Name: JimmysWorldDB
Driver Source: Built-in library
The tables used here are as follows:
1. UserLogins
Column 1 : UserID
Column 2 : FullName
Column 3 : Username
Column 4 : Password
Column 5 : HasAccess
2. LoginRecords
Column 1 : RecordID
Column 2 : Date
Column 3 : Logon <--- This is a time field
Column 4 : Logoff <--- This is a time field
Column 5 : Username
So basically I would like to know how to make the app check the verify the Username and Password and only if the member HasAccess = true then have a successful login. <--- All from UserLogins table
Then if the user has logged in successfully, save a LoginRecord where it puts the date, login time and the username.
My code is as follows below.
LoginActivity.kt
name of the button is button_login
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.Toast
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.jimmysworld.MainActivity
import com.jimmysworld.R
import com.jimmysworld.databinding.ActivityLoginBinding
class LoginActivity : AppCompatActivity() {
private lateinit var loginViewModel: LoginViewModel
private lateinit var binding: ActivityLoginBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
val username = binding.username
val password = binding.password
val login = binding.login
val loading = binding.loading
loginViewModel = ViewModelProvider(this, LoginViewModelFactory())[LoginViewModel::class.java]
loginViewModel.loginFormState.observe(this#LoginActivity, Observer {
val loginState = it ?: return#Observer
// disable login button unless both username / password is valid
login.isEnabled = loginState.isDataValid
if (loginState.usernameError != null) {
username.error = getString(loginState.usernameError)
}
if (loginState.passwordError != null) {
password.error = getString(loginState.passwordError)
}
})
loginViewModel.loginResult.observe(this#LoginActivity, Observer {
val loginResult = it ?: return#Observer
loading.visibility = View.GONE
if (loginResult.error != null) {
showLoginFailed(loginResult.error)
}
if (loginResult.success != null) {
updateUiWithUser(loginResult.success)
}
setResult(Activity.RESULT_OK)
//Complete and destroy login activity once successful
finish()
})
username.afterTextChanged {
loginViewModel.loginDataChanged(
username.text.toString(),
password.text.toString()
)
}
password.apply {
afterTextChanged {
loginViewModel.loginDataChanged(
username.text.toString(),
password.text.toString()
)
}
setOnEditorActionListener { _, actionId, _ ->
when (actionId) {
EditorInfo.IME_ACTION_DONE ->
loginViewModel.login(
username.text.toString(),
password.text.toString()
)
}
false
}
login.setOnClickListener {
loading.visibility = View.VISIBLE
loginViewModel.login(username.text.toString(), password.text.toString())
}
}
}
private fun updateUiWithUser(model: LoggedInUserView) {
val welcome = getString(R.string.welcome)
val displayName = model.displayName
// TODO : initiate successful logged in experience
Toast.makeText(
applicationContext,
"$welcome $displayName",
Toast.LENGTH_LONG
).show()
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
}
private fun showLoginFailed(#StringRes errorString: Int) {
Toast.makeText(applicationContext, errorString, Toast.LENGTH_SHORT).show()
}
}
LoginViewModel.kt
import android.util.Patterns
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.jimmysworld.R
import com.jimmysworld.data.LoginRepository
import com.jimmysworld.data.Result
class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel() {
private val _loginForm = MutableLiveData<LoginFormState>()
val loginFormState: LiveData<LoginFormState> = _loginForm
private val _loginResult = MutableLiveData<LoginResult>()
val loginResult: LiveData<LoginResult> = _loginResult
fun login(username: String, password: String) {
// can be launched in a separate asynchronous job
val result = loginRepository.login(username, password)
val user = "Admin"
val pass = "1234567"
if (username.toString() == user && password.toString() == pass) {
if (result is Result.Success) {
_loginResult.value =
LoginResult(success = LoggedInUserView(displayName = result.data.displayName))
}
} else {
_loginResult.value = LoginResult(error = R.string.login_failed)
}
}
fun loginDataChanged(username: String, password: String) {
if (!isUserNameValid(username)) {
_loginForm.value = LoginFormState(usernameError = R.string.invalid_username)
} else if (!isPasswordValid(password)) {
_loginForm.value = LoginFormState(passwordError = R.string.invalid_password)
} else {
_loginForm.value = LoginFormState(isDataValid = true)
}
}
// A placeholder username validation check
private fun isUserNameValid(username: String): Boolean {
return if (username.contains('#')) {
Patterns.EMAIL_ADDRESS.matcher(username).matches()
} else {
username.isNotBlank()
}
}
// A placeholder password validation check
private fun isPasswordValid(password: String): Boolean {
return password.length > 7
}
}
LoggedInUser
import com.jimmysworld.data.model.LoggedInUser
class LoginRepository(val dataSource: LoginDataSource) {
var user: LoggedInUser? = null
private set
val isLoggedIn: Boolean
get() = user != null
init {
user = null
}
fun logout() {
user = null
dataSource.logout()
}
fun login(username: String, password: String): Result<LoggedInUser> {
// handle login
val result = dataSource.login(username, password)
if (result is Result.Success) {
setLoggedInUser(result.data)
}
return result
}
private fun setLoggedInUser(loggedInUser: LoggedInUser) {
this.user = loggedInUser
}
}
LoginViewModelFactory.kt
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.jimmysworld.data.LoginDataSource
import com.jimmysworld.data.LoginRepository
class LoginViewModelFactory : ViewModelProvider.Factory {
#Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(LoginViewModel::class.java)) {
return LoginViewModel(
loginRepository = LoginRepository(
dataSource = LoginDataSource()
)
) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
I am sorry for it being so long winded and appreciate any help I can get.
Thanks in advance.
You probably need a database driver.
I have not written for Android, but it looks like Android does not natively support mysql db connections. One way to make this happen is to use a PHP middleman. That's wild.
Here is a link about using PHP for this purpose. https://www.tutorialspoint.com/android/android_php_mysql.htm
Firebase problem!(It's not connected with not having the internet in emulator Or with enabling auth in firebase menu) When i created login and password everything worked fine after that i connected Realtime database and since that i get an error "ignoring header X-Firebase-Locale because its value was null." When i delete database and leave only registration and login everything works fine.
// change means what i changed since i created realtime database
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast register activity
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
class Register : AppCompatActivity() {
private lateinit var edtEmail2: EditText
private lateinit var edtPassword2: EditText
private lateinit var edtName: EditText //change
private lateinit var btnSignUp2: Button
private lateinit var mAuth: FirebaseAuth
private lateinit var mDbRef: DatabaseReference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
supportActionBar?.hide() //change
edtName = findViewById(R.id.name) //change2
edtEmail2 = findViewById(R.id.Email2)
edtPassword2 = findViewById(R.id.Password2)
btnSignUp2 = findViewById(R.id.Register2)
mAuth = FirebaseAuth.getInstance()
btnSignUp2.setOnClickListener {
val email = edtEmail2.text.toString()
val name = edtName.text.toString() //change
val password = edtPassword2.text.toString()
signUp(email, password, name) // change
}
}
private fun signUp(name: String, email: String, password: String) { //change
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
//code for jumping to profile
addUserToDatabase(name,email,mAuth.currentUser?.uid!!) //change
val intent = Intent(this#Register, Profile::class.java)
startActivity(intent)
} else {
Toast.makeText(this#Register, "An error has occured", Toast.LENGTH_SHORT).show() //Ohhh
}
}
}
//Ohhh //Ohhh
Please add some context to explain the code sections (or check that you have not incorrectly formatted all of your question as code).
private fun addUserToDatabase(name: String, email: String, uid: String){ //change
mDbRef = FirebaseDatabase.getInstance().reference
mDbRef.child("user").child(uid).setValue(User(name, email, uid)) //change
}
}
I am new to Android. I create sign-in and sign-up functionality. But I want to store the data of the user,(before going to the signing screen) when the user is signing up in the FireBase FireStore (based on the current user id). I have the user id, but I don't know the way to do it. The code is attached below. I am glad, If someone could help.
package com.example.firebase
import android.content.Intent
import android.os.Binder
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import com.example.firebase.databinding.ActivitySignUpBinding
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.DocumentReference
import com.google.firebase.firestore.FirebaseFirestore
class Sign_Up_Activity : AppCompatActivity() {
private lateinit var binding: ActivitySignUpBinding
private lateinit var firebaseAuth: FirebaseAuth
private lateinit var firebasefirestore: FirebaseFirestore
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySignUpBinding.inflate(layoutInflater)
setContentView(binding.root)
firebaseAuth = FirebaseAuth.getInstance()
firebasefirestore = FirebaseFirestore.getInstance()
binding.signUpButton.setOnClickListener {
val email = binding.emailEt.text.toString()
val password = binding.passET.text.toString()
val confirmPass = binding.confirmPassEt.text.toString()
if (email.isNotEmpty() && password.isNotEmpty() && confirmPass.isNotEmpty()) {
if (password.equals(confirmPass)) {
firebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener {
if (it.isSuccessful) {
val userid:String= firebaseAuth.currentUser!!.uid
firebasefirestore.collection("user").document(userid).get()
Log.d("User id",userid)
val intent = Intent(this, Sign_In_Activity::class.java)
startActivity(intent)
} else {
Toast.makeText(this, it.exception.toString(),
Toast.LENGTH_SHORT)
.show()
}
}
} else {
Toast.makeText(this, "Password is not matching",
Toast.LENGTH_SHORT).show()
}
} else {
Toast.makeText(this, "Empty Fields are not Allowed",
Toast.LENGTH_SHORT).show()
}
}
}
}
When you're using the following line of code:
firebasefirestore.collection("user").document(userid).get()
You aren't setting the user to Firestore, you're only reading it. If you want to add the data to the database, you have to use set() like in the following lines of code:
val db = Firebase.firestore
val user = mapOf("email" to firebaseAuth.currentUser!!.email)
val userRef = db.collection("user")
userRef.document(userid).set(user)
.addOnSuccessListener { Log.d(TAG, "DocumentSnapshot successfully written!") }
.addOnFailureListener { e -> Log.w(TAG, "Error writing document", e) }
If you're interested in implementing Firebase authentication with Google, then please check the following article:
How to authenticate to Firebase using Google One Tap in Jetpack Compose?
If you want by chance to implement the anonymous authentication, then please check:
How to handle Firebase Authentication in clean architecture using Jetpack Compose?
I am building a registration activity for my app. I am using Kotlin und Firebase authentication. The registrazion itself already workds perfectly well (as well as the login acitivity).
My next goal is to save the user data (first of all the email) in the firebase database if the registration was successfull.
The function that I am using for that looks like that:
fun writeNewUser(userId: String, email: String) {
val user = User(email)
database.child("users").child(userId).setValue(user)
}
Here is the complete activity. There are no errors, my current problem is that the writeNewUser function is never used. Does anyone know why that could be?
package com.carlschwein.servus
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.ktx.auth
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ktx.database
import com.google.firebase.ktx.Firebase
class RegistrationActivity : AppCompatActivity() {
lateinit var etEmail: EditText
lateinit var etConfPass: EditText
private lateinit var etPass: EditText
private lateinit var btnSignUp: Button
lateinit var tvRedirectLogin: TextView
private lateinit var auth: FirebaseAuth
private lateinit var database: DatabaseReference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.registration)
// View Bindings
etEmail = findViewById(R.id.etSEmailAddress)
etConfPass = findViewById(R.id.etSConfPassword)
etPass = findViewById(R.id.etSPassword)
btnSignUp = findViewById(R.id.btnSSigned)
tvRedirectLogin = findViewById(R.id.tvRedirectLogin)
database = Firebase.database.reference
// Initialising auth object
auth = Firebase.auth
btnSignUp.setOnClickListener {
signUpUser()
}
// switching from signUp Acitity to Login Activity
tvRedirectLogin.setOnClickListener {
startActivity(Intent(this, LoginActivity::class.java))
}
}
private fun signUpUser() {
val email = etEmail.text.toString()
val pass = etPass.text.toString()
val confirmPassword = etConfPass.text.toString()
// check pass
if (email.isBlank() || pass.isBlank() || confirmPassword.isBlank()) {
Toast.makeText(this, "Email und/oder Passwort dürfen nicht leer sein.", Toast.LENGTH_SHORT).show()
return
}
if (pass != confirmPassword) {
Toast.makeText(this, "Die beiden Passwörter stimmen nicht überein.", Toast.LENGTH_SHORT)
.show()
return
}
// If all credential are correct
// We call createUserWithEmailAndPassword
// using auth object and pass the
// email and pass in it.
auth.createUserWithEmailAndPassword(email, pass).addOnCompleteListener(this) {
if (it.isSuccessful) {
Toast.makeText(this, "Registrierung erfolgreich!", Toast.LENGTH_SHORT).show()
fun writeNewUser(userId: String, email: String) {
val user = User(email)
database.child("users").child(userId).setValue(user)
}
startActivity(Intent(this,LoginActivity::class.java))
finish()
} else {
Toast.makeText(this, "Registrierung fehlgeschlagen. Daten bereits vorhanden oder fehlerhaft.", Toast.LENGTH_SHORT).show()
}
}
}
}
fun writeNewUser(userId: String, email: String) is not being called, you can move the function declaration outside of the completion listener attached to createUserWithEmailAndPassword then call the function inside.
Like:
if (it.isSuccessful) {
Toast.makeText(this, "Registrierung erfolgreich!", Toast.LENGTH_SHORT).show()
>>>>>> HERE
val uid = auth.currentUser.uid
writeNewUser(uid, email)
startActivity(Intent(this,LoginActivity::class.java))
finish()
} else {
Toast.makeText(this, "Registrierung fehlgeschlagen. Daten bereits vorhanden oder fehlerhaft.", Toast.LENGTH_SHORT).show()
}
I'm trying to figure out how to add more users in a Login app made with Kotlin, there's no database or whatever, the accounts are hardcoded into the program, I heard about using arrays but I'm not too sure on how to implement it in this context.
Thank you to anyone who reads this.
package com.example.textandviewbinding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import android.widget.Toast
import com.example.textandviewbinding.databinding.ActivityMainBinding
import com.google.android.material.snackbar.Snackbar
import java.util.*
import kotlin.system.exitProcess
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.btnSubmit.setOnClickListener {
validateUser(it)
}
}
private fun addTextView(text:String){
val textView1 = TextView(this)
textView1.text = text
textView1.textSize = 16f
textView1.textAlignment = View.TEXT_ALIGNMENT_CENTER
binding.myLayout.addView(textView1)
}
private fun validateUser(it: View) {
val username = binding.editUsername.text
val password = binding.editPassword.text
if (username.toString().equals("joed", ignoreCase = true) && password.toString().equals("1234")) {
// Toast.makeText(this, "Logged In!", Toast.LENGTH_SHORT).show()
val message = getString(R.string.welcome_message,username)
Snackbar.make(it, message, Snackbar.LENGTH_LONG)
.setAction("Show details.. ", { addTextView("Login Successful: ${Calendar.getInstance().time}" ) })
.show()
} else {
Toast.makeText(this, "Invalid Details", Toast.LENGTH_SHORT).show()
exitProcess(-1)
}
}
private fun displayToast() {
Toast.makeText(this, "Login Successful ${Calendar.getInstance().time}", Toast.LENGTH_SHORT).show()
}
}
1- Create a class called User , ex:
data class User(
var id : Int
var name : String
)
2- Create an Array of users using the User model in your MainActivity :
private val users = ArrayList<User>()
3- Add users to the array :
users.add(User(1,"Alex"))
users.add(User(2,"Andrei"))