My problem is that I want save the uid, username and his profileImageUrl. All variables give the output that I need except "user" (I think).
This is the function to save the user to database:
private fun saveUserToFirebaseDatabase(profileImageUrl: String) {
val uid = FirebaseAuth.getInstance().uid ?: ""
val ref = FirebaseDatabase.getInstance().getReference("/users/$uid")
val user = User(uid, username_edittext_register.text.toString(), profileImageUrl)
ref.setValue(user)
.addOnSuccessListener {
Log.d("RegisterActivity", "Finally we saved the user to Firebase Database")
val intent = Intent(this,LatestMessagesActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
.addOnFailureListener{
Log.d("RegisterActivity", "Failed to set value to database: ${it.message}")
}
Log.d("saveUserToDatabase","Task completed? User: $user")
}
This the class User:
class User(val uid: String,val username: String,val profileImageUrl: String) {
constructor() : this("", "", "")
}
This is the "whole" code:
package letsbuildthatapp.com
import android.app.Activity
import android.content.ContentValues.TAG
import android.content.Intent
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import kotlinx.android.synthetic.main.activity_register.*
import java.util.*
class RegisterActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
register_button_register.setOnClickListener {
performRegister()
}
already_have_account_text_view.setOnClickListener {
Log.d("RegisterActivity", "Try to show login activity")
//Launch the login activity somehow
val intent = Intent(this, LoginActivity::class.java)
startActivity(intent)
}
selectphoto_button_register.setOnClickListener {
Log.d("RegisterActivity", "Try to show photo selector")
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, 0)
}
}
var selectedPhotoUri: Uri? = null
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 0 && resultCode == Activity.RESULT_OK && data != null) {
Log.d("RegisterActivity", "Photo was selected")
selectedPhotoUri = data.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver,selectedPhotoUri)
select_photo_imageView_register.setImageBitmap(bitmap)
selectphoto_button_register.alpha = 0f
}
}
private fun performRegister() {
val username = username_edittext_register.text.toString()
val email = email_edittext_register.text.toString()
val password = password_edittext_register.text.toString()
if (email.isEmpty() || password.isEmpty()) {
Toast.makeText(this,"Please enter text in email/password", Toast.LENGTH_SHORT).show()
return
}
Log.d("RegisterActivity", "Username: $username")
Log.d("RegisterActivity", "Email is: $email")
Log.d("RegisterActivity", "Password: $password")
// Firebase Authentication to create a user with email and password
FirebaseAuth.getInstance().createUserWithEmailAndPassword(email, password)
.addOnCompleteListener{
if (!it.isSuccessful) return#addOnCompleteListener
//else if successful
Log.d("RegisterActivity", "Successfully created user with uid: ${it.result.user!!.uid}")
uploadImageToFirebaseStorage()
}
.addOnFailureListener{
Log.d("RegisterActivity","Failed to create user: ${it.message}")
Toast.makeText(this,"Failed to create user: ${it.message}", Toast.LENGTH_SHORT).show()
}
}
private fun uploadImageToFirebaseStorage() {
if (selectedPhotoUri == null) return
val filename = UUID.randomUUID().toString()
val ref = FirebaseStorage.getInstance().getReference("/images/$filename")
ref.putFile(selectedPhotoUri!!)
.addOnSuccessListener {
Log.d("RegisterActivity", "Successfully uploaded image: ${it.metadata?.path}")
ref.downloadUrl.addOnSuccessListener {
Log.d("RegisterActivity", "File Location: $it")
saveUserToFirebaseDatabase(it.toString())
}
}
.addOnFailureListener{
Log.d("RegisterActivity", "Failed")
Toast.makeText(this,"Failed: ${it.message}", Toast.LENGTH_SHORT).show()
}
}
private fun saveUserToFirebaseDatabase(profileImageUrl: String) {
val uid = FirebaseAuth.getInstance().uid ?: ""
val ref = FirebaseDatabase.getInstance().getReference("/users/$uid")
val user = User(uid, username_edittext_register.text.toString(), profileImageUrl)
ref.setValue(user)
.addOnSuccessListener {
Log.d("RegisterActivity", "Finally we saved the user to Firebase Database")
val intent = Intent(this,LatestMessagesActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
.addOnFailureListener{
Log.d("RegisterActivity", "Failed to set value to database: ${it.message}")
}
Log.d("saveUserToDatabase","Task completed? User: $user")
}
}
class User(val uid: String,val username: String,val profileImageUrl: String) {
constructor() : this("", "", "")
}
This is the output of "user": letsbuildthatapp.com.User#41cb40
I found the Solution for this Problem. It's really simple and making me sad that I get now after a day.
val ref = FirebaseDatabase.getInstance(Type here the Url of the database!).getReference("/users/$uid")
Related
I've recently started programming in Kotlin and cannot seem to add a profile picture to a user when registering it.
According to the code here, I can access to the gallery and retrieve the image information. The picture will appear on screen, but after registering the user the image url will not appear anywhere.
class RegisterUser : AppCompatActivity() {
private val database = FirebaseDatabase.getInstance()
private val auth: FirebaseAuth = FirebaseAuth.getInstance()
private val UserCreation = database.getReference("Usuarios")
private val pickImage = 100
private var imageUri: Uri? = null
lateinit var imageView: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register_user)
Goback.setOnClickListener {
val Gobackou = Intent(this, MainActivity::class.java)
startActivity(Gobackou)
}
RegisterConfirm.setOnClickListener {
val SetUser = SetUser.text.toString()
val SetPass = setPass.text.toString()
val SetEmail = SetEmail.text.toString()
if (SetUser.isEmpty() && SetPass.isEmpty() && SetEmail.isEmpty()) {
Toast.makeText(this, "Faltan Campos", Toast.LENGTH_SHORT).show()
} else {
RegisterUserv2(SetEmail, SetPass, SetUser)
}
}
selectPP.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, pickImage)
}
}
var selectedPhotoUri: Uri? = null
//guardar la foto de perfil
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == pickImage) {
val selectedPhotoUri = data?.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
val bitmapDrawable = BitmapDrawable(bitmap)
userimg.setBackgroundDrawable(bitmapDrawable)
}
}
private fun RegisterUserv2(email: String, password: String, user: String) {
auth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
uploadimage()
UltrasaveUsuario(Usuarios(auth.currentUser!!.uid, user, password, email))
val Gobackou = Intent(this, MainActivity::class.java)
startActivity(Gobackou)
} else {
Toast.makeText(this, "Registro ERROR", Toast.LENGTH_LONG).show()
}
}
}
private fun UltrasaveUsuario(usuario: Usuarios) {
val mensajeFirebase = UserCreation.push()
usuario.id = mensajeFirebase.key ?: ""
mensajeFirebase.setValue(usuario)
}
private fun uploadimage(imageurl: String){
if (selectedPhotoUri == null) return
val filename = UUID.randomUUID().toString()
val ref = FirebaseStorage.getInstance().getReference("/images/$filename/")
ref.putFile(selectedPhotoUri!!)
.addOnSuccessListener {
ref.downloadUrl.addOnSuccessListener{
}
}
}
}
Since you are using firebase I will show you how to save firebase storage.
private fun uploadImage() {
if (mSelectedImageFileUri != null) {
val sRef: StorageReference = FirebaseStorage.getInstance().reference.child(
"users/ $uid/profile.jpg"
)
sRef.putFile(mSelectedImageFileUri!!)
.addOnSuccessListener { taskSnapshot ->
taskSnapshot.metadata!!.reference!!.downloadUrl
.addOnSuccessListener { url ->
}
}.addOnFailureListener {
//error
}
} else {
}
}
then you will take this picture using the user id to take .
firebase>storage to view the image
getImage
val sRef: StorageReference = FirebaseStorage.getInstance().reference.child(
"users/ $uid/profile.jpg"
)
sRef.downloadUrl.addOnSuccessListener {
Picasso.get().load(it).into(globalprofileImage)
}
Build.gradle
implementation 'com.squareup.picasso:picasso:2.71828'
https://www.youtube.com/watch?v=nNYLQcmB7AU&t=449s&ab_channel=SmallAcademy
I am stuck in a strange problem that is when i save data from 1 activity (Parent Page) it saves data. and on reload app it loads the saved preferences and user don't have to sign in again and again. But when i tried to do this with child it didn't helped :(
Here is my code for Parent:
class SignIn : AppCompatActivity() {
private val sharedPrefFile = Common.APP_NAME
private var auth: FirebaseAuth = Firebase.auth
private lateinit var usertype: String
val db = Firebase.firestore
lateinit var etEmail: String
lateinit var etPassword: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
getData()
_sign_in_as.setText("signing in as " + usertype)
//SignIn button
_btn_sign_in.setOnClickListener{
etEmail = _sign_in_email.text.toString()
etPassword =_sign_in_password.text.toString()
AuthenticateUser(etEmail,etPassword)
}
//Signup Link
_sign_in_screen_sign_up_link.setOnClickListener{
//Creating Intent
val intent = Intent(this, ParentSignup::class.java)
startActivity(intent)
}
}
private fun AuthenticateUser(email: String, password: String){
_progressBar.visibility= View.VISIBLE
_progressBar.visibility= View.INVISIBLE
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success, update UI with the signed-in user's information
Log.d(TAG, "signInWithEmail:success")
db.collection(USER_COLLECTION)
.whereEqualTo(USER_EMAIL,email)
.get()
.addOnSuccessListener { documents ->
for (document in documents){
val intent = Intent(this, TabbedActivity::class.java)
//Saving UserType in Shared Preferences
val sharedPreferences: SharedPreferences = getSharedPreferences(sharedPrefFile, Context.MODE_PRIVATE)
val sharedPref: SharedPreferences.Editor = sharedPreferences.edit()
//Email
sharedPref.putString(USER_EMAIL, document.data[USER_EMAIL].toString())
sharedPref.apply()
//username
sharedPref.putString(USER_NAME, document.data[USER_NAME].toString())
sharedPref.apply()
//number
sharedPref.putString(USER_PHONE, document.data[USER_PHONE].toString())
sharedPref.apply()
//number
sharedPref.putString(Common.LOGIN_STATUS, Common.LOGGED_IN)
sharedPref.apply()
Common.userName = document.data[USER_NAME].toString()
Common.userEmail = document.data[USER_EMAIL].toString()
Common.userPhone = document.data[USER_PHONE].toString()
startActivity(intent)
finishAffinity()
}
}
} else {
_progressBar.visibility= View.INVISIBLE
// If sign in fails, display a message to the user.
Log.w(TAG, "signInWithEmail:failure", task.exception)
Toast.makeText(baseContext, "Authentication failed." + (task.getException()?.message
?: ""),
Toast.LENGTH_SHORT).show()
}
}
}
fun getData(){
val sharedPreferences: SharedPreferences = getSharedPreferences(sharedPrefFile, Context.MODE_PRIVATE)
val sharedPref: SharedPreferences = sharedPreferences
usertype = sharedPref.getString(USER_TYPE, "").toString()
}
}
Here is code for Child:
class ChildSignup : AppCompatActivity() {
private val sharedPrefFile = Common.APP_NAME
private lateinit var auth: FirebaseAuth
val db = Firebase.firestore
private val TAG = "testTag"
private lateinit var code: String
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_child_signup)
auth = Firebase.auth
//Linking Parent Email
_btn_link_child.setOnClickListener {
verifyParentEmail()
}
//Verifying Email
_btn_sign_up_verify.setOnClickListener{
saveInSharedPreferences()
linkChild()
}
_child_sign_up_parent_link.setOnClickListener{
val intent = Intent(this, SignIn::class.java)
startActivity(intent)
finishAffinity()
}
}
private fun saveInSharedPreferences() {
//Saving UserType in Shared Preferences
val sharedPreferences: SharedPreferences = getSharedPreferences(sharedPrefFile, Context.MODE_PRIVATE)
val sharedPref: SharedPreferences.Editor = sharedPreferences.edit()
//Email
sharedPref.putString(USER_EMAIL, _link_child_email.text.toString())
sharedPref.apply()
//username
sharedPref.putString(USER_NAME, _link_child_name.text.toString())
sharedPref.apply()
//number
sharedPref.putString(USER_PHONE, "03154970584")
sharedPref.apply()
//number
sharedPref.putString(LOGIN_STATUS, LOGGED_IN)
sharedPref.apply()
//userType
sharedPref.putString(USER_TYPE, USER_TYPE_CHILD)
sharedPref.apply()
Common.userType = USER_TYPE_CHILD
Common.userEmail = _link_child_email.text.toString()
Common.userName = _link_child_name.text.toString()
Toast.makeText(this, sharedPreferences.getString(USER_EMAIL, ""), Toast.LENGTH_SHORT).show()
Toast.makeText(this, sharedPreferences.getString(USER_NAME, ""), Toast.LENGTH_SHORT).show()
Toast.makeText(this, sharedPreferences.getString(USER_TYPE, ""), Toast.LENGTH_SHORT).show()
}
private fun verifyParentEmail() {
var flag = false
code =(100000..999999).random().toString()
Log.d("TAG:", code)
Toast.makeText(this, code, Toast.LENGTH_LONG).show()
auth.fetchSignInMethodsForEmail(_link_child_email.text.toString()).addOnSuccessListener(this) { task ->
if (!task.signInMethods?.isEmpty()!!){
db.collection(LINKED_CHILDS)
.whereEqualTo(USER_EMAIL,_link_child_email.text.toString())
.get()
.addOnSuccessListener { documents ->
for (document in documents){
if (document[USER_NAME] == _link_child_name.text.toString()){
flag = true
}
}
if (flag == true){
Toast.makeText(this, "This child is already linked with this parent!\nPlease verify code to continue", Toast.LENGTH_SHORT)
.show()
}
sendEmail(_link_child_email.text.toString(),
_link_child_name.text.toString(),
code,
"Email Verification Code"
)
_child_signup_verify_layout.isVisible = true
}
}
else{
Toast.makeText(this, "No Such parent found", Toast.LENGTH_SHORT)
.show()
}
}
}
#RequiresApi(Build.VERSION_CODES.O)
private fun linkChild() {
if (_sign_up_six_digit_code.text.toString() == code){
saveToCloud()
}
}
#RequiresApi(Build.VERSION_CODES.O)
private fun saveToCloud() {
val thread = Thread {
try {
//Your code goes here
val user = hashMapOf(
USER_TYPE to USER_TYPE_CHILD,
USER_EMAIL to _link_child_email.text.toString(),
USER_NAME to _link_child_name.text.toString(),
TOKEN to "" ,
DATE to LocalDate.now().toString(),
DAY to LocalDate.now().dayOfWeek.toString()
)
db.collection(Common.LINKED_CHILDS).add(user).addOnSuccessListener { documentReference ->
Log.d(TAG, "DocumentSnapshot added with ID: ${documentReference.id}")
//Moving to Next Screen
val intent = Intent(this, TabbedActivity::class.java)
// intent.putExtra(USER_TYPE, USER_TYPE_CHILD)
startActivity(intent)
// finishAffinity()
}.addOnFailureListener { e ->
Log.w(TAG, "Error adding document", e)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
thread.start()
Log.d("Thread status: ", "Started")
}
}
And I am checking preferences here:
class MainActivity : AppCompatActivity() {
private val sharedPrefFile = Common.APP_NAME
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sharedPreferences: SharedPreferences = getSharedPreferences(sharedPrefFile, Context.MODE_PRIVATE)
//UserType
Toast.makeText(this, sharedPreferences.getString(USER_TYPE, "1"), Toast.LENGTH_SHORT).show()
Toast.makeText(this, sharedPreferences.getString(USER_EMAIL, "2"), Toast.LENGTH_SHORT).show()
Toast.makeText(this, sharedPreferences.getString(USER_NAME, "3"), Toast.LENGTH_SHORT).show()
if (sharedPreferences.getString(USER_TYPE, "") == "" || sharedPreferences.getString(
USER_EMAIL, "") == "" || sharedPreferences.getString(USER_NAME, "") == ""){
Handler(Looper.getMainLooper()).postDelayed({
val intent = Intent(this, WelcomeScreen::class.java)
startActivity(intent)
finish()
},2000)
}
else{
userType = sharedPreferences.getString(USER_TYPE, "").toString()
userEmail = sharedPreferences.getString(USER_EMAIL, "").toString()
userName = sharedPreferences.getString(USER_NAME, "").toString()
val intent = Intent(this, TabbedActivity::class.java)
startActivity(intent)
finishAffinity()
}
}
}
I'm creating password retrieving mechanism for login page with real time database from firebase.
Everything runs well but the first time I press "submit" button, my mutable dataset is not up to date yet to save the password data. When I press second time, the mutable dataset is updated with the data and hence I can log into the system. Any idea how to fix this?
my code 2
my code 1
package com.example.mytrack2
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.ContactsContract
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import androidx.core.text.trimmedLength
import com.google.firebase.database.*
import com.google.firebase.database.ktx.getValue
class SignInActivity : AppCompatActivity() {
// late init everything here
lateinit var goBack: Button //go back button
lateinit var signInUser: Button
lateinit var verifyUsername: EditText
lateinit var verifyPassword: EditText
lateinit var myRef: DatabaseReference
var dataSet = mutableSetOf<String>("admin")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_sign_in)
// assign every ID here
goBack = findViewById(R.id.back)
signInUser = findViewById(R.id.signInUser) // Button to submit
verifyPassword = findViewById(R.id.verifyPassword) // user input for password
verifyUsername = findViewById(R.id.verifyUsername) // user input for username
// create database reference scanner
myRef = FirebaseDatabase.getInstance().reference // reference
var strUsername = ""
var strPassword = ""
// setup all button here
val getPassword = object: ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for(item in snapshot.children){
var namename = snapshot.child("PASSWORD").value.toString()
dataSet.add(namename)
}
}
override fun onCancelled(error: DatabaseError) {
//
}
}
signInUser.setOnClickListener {
val goIntent = Intent(this, HomeActivity::class.java)
strUsername = verifyUsername.text.toString().trim()
strPassword = verifyPassword.text.toString().trim()
myRef = myRef.child(strUsername)
myRef.addValueEventListener(getPassword) // check user password
myRef.addListenerForSingleValueEvent(getPassword) // check user password
if (strUsername.trimmedLength() == 0 || strPassword.trimmedLength() == 0){
Toast.makeText(this#SignInActivity, "Please fill in the field!", Toast.LENGTH_SHORT).show()
}
else
{
if(dataSet.contains(strPassword))
{
Toast.makeText(this#SignInActivity, "Login Successfully!", Toast.LENGTH_SHORT).show()
startActivity(goIntent)
}
else
{
Toast.makeText(this#SignInActivity, "$dataSet", Toast.LENGTH_SHORT).show()
Toast.makeText(this#SignInActivity, "Incorrect password!", Toast.LENGTH_SHORT).show()
}
}
}
// setup the goback button
goBack.setOnClickListener{
val goBackIntent = Intent(this, MainActivity::class.java)
startActivity(goBackIntent)
}
}
}
Any code that needs the data from the database, must be inside the onDataChange method:
signInUser.setOnClickListener {
val goIntent = Intent(this, HomeActivity::class.java)
strUsername = verifyUsername.text.toString().trim()
strPassword = verifyPassword.text.toString().trim()
myRef = myRef.child(strUsername)
myRef.addListenerForSingleValueEvent(object: ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
for(item in snapshot.children){
var namename = snapshot.child("PASSWORD").value.toString()
dataSet.add(namename)
}
if (strUsername.trimmedLength() == 0 || strPassword.trimmedLength() == 0){
Toast.makeText(this#SignInActivity, "Please fill in the field!", Toast.LENGTH_SHORT).show()
}
else
{
if(dataSet.contains(strPassword))
{
Toast.makeText(this#SignInActivity, "Login Successfully!", Toast.LENGTH_SHORT).show()
startActivity(goIntent)
}
else
{
Toast.makeText(this#SignInActivity, "$dataSet", Toast.LENGTH_SHORT).show()
Toast.makeText(this#SignInActivity, "Incorrect password!", Toast.LENGTH_SHORT).show()
}
}
}
override fun onCancelled(error: DatabaseError) {
Log.e("Firebase", "Error loading data", error.exception) // 👈 don't ignore errors
}
}) // check user password
}
Here I'm trying to upload an image from the local storage to the firebase storage.
I'm uploading the image using its URI
package com.example.demochat
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.storage.FirebaseStorage
import java.util.*
class RegisterActivity : AppCompatActivity() {
private lateinit var username: EditText
private lateinit var email: EditText
private lateinit var password: EditText
private lateinit var register: Button
private lateinit var haveAccount: TextView
private lateinit var imageInsert: Button
private lateinit var imageView: ImageView
private val tag: String = "RegisterActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_register)
username = findViewById(R.id.editTextUsername)
email = findViewById(R.id.editTextTextEmailAddress)
password = findViewById(R.id.editTextTextPassword)
register = findViewById(R.id.buttonRegister)
haveAccount = findViewById(R.id.textViewAlready_have_an_account)
imageInsert = findViewById(R.id.buttonInsertImage)
imageView = findViewById(R.id.imageViewImageInsert)
imageInsert.setOnClickListener {
selectImage()
}
register.setOnClickListener {
performRegister()
}
haveAccount.setOnClickListener {
val intent = Intent(this#RegisterActivity, LoginActivity::class.java)
startActivity(intent)
}
}
private var selectedPhotoUri: Uri? = null
private fun selectImage() {
Log.d(tag, "clicked image button")
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(intent, 100)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 100 && resultCode == RESULT_OK && data != null && data.data != null) {
Toast.makeText(this#RegisterActivity, "clicked image selected", Toast.LENGTH_SHORT)
.show()
val selectedPhotoUri = data.data
Toast.makeText(this#RegisterActivity, "$selectedPhotoUri", Toast.LENGTH_SHORT).show()
imageView.setImageURI(selectedPhotoUri)
}
}
private fun performRegister() {
if (email.text.isEmpty() || password.text.isEmpty()) {
Toast.makeText(this, "Fill the above details", Toast.LENGTH_SHORT).show()
return
}
FirebaseAuth.getInstance()
.createUserWithEmailAndPassword(email.text.toString(), password.text.toString())
.addOnCompleteListener {
if (!it.isSuccessful) return#addOnCompleteListener
Log.d(tag, "uid = ${it.result?.user?.uid}")
uploadImageToFirebase()
}
.addOnFailureListener {
Toast.makeText(this, "${it.message}", Toast.LENGTH_SHORT).show()
Log.d(tag, "${it.message}")
}
}
private fun uploadImageToFirebase() {
if (selectedPhotoUri == null) return
val fileName = UUID.randomUUID().toString() + ".jpg"
val refStorage = FirebaseStorage.getInstance().reference.child("/images/$fileName")
refStorage.putFile(selectedPhotoUri!!)
.addOnSuccessListener {
Log.d(tag, "image uploaded")
}
.addOnFailureListener {
Log.d("RegisterActivity", "${it.message}")
}
}
}
following is the rules for the firebase stroage
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
firebase authentication part is working fine, users are added successfully. But I'm unable to upload an image. I have included internet permissions in the manifest file.
And I'm not getting any error message
So, please help
Here:
val selectedPhotoUri = data.data
you are not reassigning the global property selectedPhotoUri, but creating a new one.
Then, here:
if (selectedPhotoUri == null) return
you are checking with the global property which is always null.
I'm having a hard time getting an image URL from firebase storage, I got the photo URL from the database, but as I know, Glide can't get a picture from the link like this: com.google.firebase.storage.UploadTask#62873ce
Here are my Storage and database references:
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
here is the function:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
I tried changing
val photoUrl = it.task.toString()
to
val photoUrl = it.downloadUrl.toString()
but it highlights 'downloadUrl' as unresolved reference
Full code:
package com.example.homeactivity.activities
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.text.Editable
import android.util.Log
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.example.homeactivity.R
import com.example.homeactivity.models.User
import com.example.homeactivity.views.PasswordDialog
import com.google.firebase.auth.AuthCredential
import com.google.firebase.auth.EmailAuthProvider
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.StorageReference
import com.google.firebase.storage.UploadTask
import kotlinx.android.synthetic.main.activity_edit_profile.*
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
class EditProfileActivity : AppCompatActivity(), PasswordDialog.Listener {
private lateinit var mImageUri: Uri
private lateinit var mStorage: StorageReference
private val TAG = "EditProfileActivity"
private lateinit var mUser: com.example.homeactivity.models.User
private lateinit var mAuth: FirebaseAuth
private lateinit var mDatabase: DatabaseReference
private lateinit var mPendingUser: com.example.homeactivity.models.User
private val TAKE_PICTURE_REQUEST_CODE = 1
val simpleDateFormat = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_edit_profile)
Log.d(TAG, "onCreate")
close_image.setOnClickListener { finish() }
save_image.setOnClickListener { updateProfile() }
change_photo_text.setOnClickListener { takeCameraPicture() }
mAuth = FirebaseAuth.getInstance()
mDatabase = FirebaseDatabase.getInstance().reference
mStorage = FirebaseStorage.getInstance().reference
mDatabase.child("users").child(mAuth.currentUser!!.uid)
.addListenerForSingleValueEvent(ValueEventListenerAdapter {
mUser = it.getValue(com.example.homeactivity.models.User::class.java)!!
name_input.setText(mUser.name, TextView.BufferType.EDITABLE)
username_input.setText(mUser.username, TextView.BufferType.EDITABLE)
website_input.setText(mUser.website, TextView.BufferType.EDITABLE)
bio_input.setText(mUser.bio, TextView.BufferType.EDITABLE)
email_input.setText(mUser.email, TextView.BufferType.EDITABLE)
phone_input.setText(mUser.phone?.toString(), TextView.BufferType.EDITABLE)
profile_image.loadUserPhoto(mUser.photo)
})
}
private fun takeCameraPicture() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (intent.resolveActivity(packageManager) != null) {
val imageFile = createImageFile()
mImageUri = FileProvider.getUriForFile(
this,
"com.example.homeactivity.fileprovider",
imageFile
)
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri)
startActivityForResult(intent, TAKE_PICTURE_REQUEST_CODE)
}
}
private fun createImageFile(): File {
val storageDir: File? = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${simpleDateFormat.format(Date())}_",
".jpg",
storageDir
)
}
#SuppressLint("MissingSuperCall")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == TAKE_PICTURE_REQUEST_CODE && resultCode == RESULT_OK) {
val uid = mAuth.currentUser!!.uid
mStorage.uploadUserPhoto(uid, mImageUri) {
val photoUrl = it.task.toString()
mDatabase.updateUserPhoto(uid, photoUrl) {
mUser = mUser.copy(photo = photoUrl)
profile_image.loadUserPhoto(mUser.photo)
}
}
}
}
private fun updateProfile() {
mPendingUser = readInputs()
val error = validate(mPendingUser)
if (error == null) {
if (mPendingUser.email == mUser.email) {
updateUser(mPendingUser)
} else {
PasswordDialog().show(supportFragmentManager, "password_dialog")
}
} else {
showToast(error)
}
}
private fun readInputs(): User {
return User(
name = name_input.text.toString(),
username = username_input.text.toString(),
email = email_input.text.toString(),
website = website_input.text.toStringOrNull(),
bio = bio_input.text.toStringOrNull(),
phone = phone_input.text.toStringOrNull()
)
}
override fun onPasswordConfirm(password: String) {
if (password.isNotEmpty()) {
val credential = EmailAuthProvider.getCredential(mUser.email, password)
mAuth.currentUser!!.reauthenticate(credential) {
mAuth.currentUser!!.updateEmail(mPendingUser.email) {
updateUser(mPendingUser)
}
}
} else {
showToast("You must enter your password")
}
}
private fun updateUser(user: com.example.homeactivity.models.User) {
val updatesMap = mutableMapOf<String, Any?>()
if (user.name != mUser.name) updatesMap["name"] = user.name
if (user.username != mUser.username) updatesMap["username"] = user.username
if (user.website != mUser.website) updatesMap["website"] = user.website
if (user.bio != mUser.bio) updatesMap["bio"] = user.bio
if (user.email != mUser.email) updatesMap["email"] = user.email
if (user.phone != mUser.phone) updatesMap["phone"] = user.phone
mDatabase.updateUser(mAuth.currentUser!!.uid, updatesMap) {
showToast("Profile saved")
finish()
}
}
private fun validate(user: com.example.homeactivity.models.User): String? =
when {
user.name.isEmpty() -> "Please enter name"
user.username.isEmpty() -> "Please enter username"
user.email.isEmpty() -> "Please enter email"
else -> null
}
private fun FirebaseUser.updateEmail(email: String, onSuccess: () -> Unit) {
updateEmail(email).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (UploadTask.TaskSnapshot) -> Unit) {
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
mStorage.child("users/$uid/photo").downloadUrl.addOnCompleteListener { task ->
if (it.isSuccessful) {
onSuccess(it.result!!)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
private fun DatabaseReference.updateUserPhoto(uid: String, photoUrl: String,
onSuccess: () -> Unit){
child("users/$uid/photo").setValue(photoUrl)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun DatabaseReference.updateUser(
uid: String, updates: Map<String, Any?>,
onSuccess: () -> Unit
) {
child("users").child(uid).updateChildren(updates)
.addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
private fun FirebaseUser.reauthenticate(credential: AuthCredential, onSuccess: () -> Unit) {
reauthenticate(credential).addOnCompleteListener {
if (it.isSuccessful) {
onSuccess()
} else {
showToast(it.exception!!.message!!)
}
}
}
}
Change your uploadUserPhoto method like this
private fun StorageReference.uploadUserPhoto(uid: String, photo: Uri,
onSuccess: (String) -> Unit) {
val uTask = mStorage.child("users/$uid/photo").putFile(mImageUri)
child("users/$uid/photo").putFile(mImageUri).addOnCompleteListener {
if (it.isSuccessful) {
uTask.continueWithTask { task ->
mStorage.child("users/$uid/photo").downloadUrl
}.addOnCompleteListener{
if (it.isSuccessful && it.result != null) {
onSuccess(it.result!!.toString)
} else {
showToast(it.exception!!.message!!)
}
}
}
}
}
In your onActivityResult use url like
val photoUrl = it