个人资料图片在Andorid Studio Kotlin中的卡片视图上显示不显示
我试图让用户个人资料图片在我的回收库中的卡上预订旁边显示。配置文件图片显示在我的NAV抽屉中,默认情况下是针对非Google用户的默认图片或Google用户的配置文件图片。但是,当我调用它时,imageuri出现空白,并且图像没有存储在我的firebase储物桶中。我已经链接了我的燃料并实施了相关的SDK。
这是我的模型。
@Parcelize
data class BookModel(
// var id : Long = 0,
var uid: String? = "",
var name: String = "N/A",
var phoneNumber: String = "N/A",
var email: String? = "N/A",
var date: String = "",
var bike: Int = 0,
var profilepic: String = "",
/*var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,*/
var pickup: String = "",
var dropoff: String = "",
var price: Double = 20.0,
/*var amount: Int = 0*/
) : Parcelable
{
@Exclude
fun toMap(): Map<String, Any?> {
return mapOf(
// "id" to id,
"uid" to uid,
"name" to name,
"phoneNumber" to phoneNumber,
"email" to email,
"date" to date,
"bike" to bike,
"profilepic" to profilepic,
"pickup" to pickup,
"dropoff" to dropoff,
"price" to price
)
}
}
@Parcelize
data class Location(
var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,
var depot: String = "Waterford"
) : Parcelable
这是我的firebaseimagemanager
package com.wit.mad2bikeshop.firebase
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.lifecycle.MutableLiveData
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.UploadTask
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
import java.io.ByteArrayOutputStream
import com.squareup.picasso.Target
object FirebaseImageManager {
var storage = FirebaseStorage.getInstance().reference
var imageUri = MutableLiveData<Uri>()
fun checkStorageForExistingProfilePic(userid: String) {
val imageRef = storage.child("photos").child("${userid}.jpg")
val defaultImageRef = storage.child("ic_book_nav_header.png")
imageRef.metadata.addOnSuccessListener { //File Exists
imageRef.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
//File Doesn't Exist
}.addOnFailureListener {
imageUri.value = Uri.EMPTY
}
}
fun uploadImageToFirebase(userid: String, bitmap: Bitmap, updating : Boolean) {
// Get the data from an ImageView as bytes
val imageRef = storage.child("photos").child("${userid}.jpg")
//val bitmap = (imageView as BitmapDrawable).bitmap
val baos = ByteArrayOutputStream()
lateinit var uploadTask: UploadTask
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
imageRef.metadata.addOnSuccessListener { //File Exists
if(updating) // Update existing Image
{
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}.addOnFailureListener { //File Doesn't Exist
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}
fun updateUserImage(userid: String, imageUri : Uri?, imageView: ImageView, updating : Boolean) {
Picasso.get().load(imageUri)
.resize(200, 200)
.transform(customTransformation())
.memoryPolicy(MemoryPolicy.NO_CACHE)
.centerCrop()
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,updating)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
fun updateDefaultImage(userid: String, resource: Int, imageView: ImageView) {
Picasso.get().load(resource)
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,false)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
}
我的firebaseauthmanager ...
package com.wit.mad2bikeshop.firebase
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.wit.mad2bikeshop.R
import timber.log.Timber
class FirebaseAuthManager(application: Application) {
private var application: Application? = null
var firebaseAuth: FirebaseAuth? = null
var liveFirebaseUser = MutableLiveData<FirebaseUser>()
var loggedOut = MutableLiveData<Boolean>()
var errorStatus = MutableLiveData<Boolean>()
var googleSignInClient = MutableLiveData<GoogleSignInClient>()
init {
this.application = application
firebaseAuth = FirebaseAuth.getInstance()
if (firebaseAuth!!.currentUser != null) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
loggedOut.postValue(false)
errorStatus.postValue(false)
FirebaseImageManager.checkStorageForExistingProfilePic(
firebaseAuth!!.currentUser!!.uid)
}
configureGoogleSignIn()
}
fun login(email: String?, password: String?) {
firebaseAuth!!.signInWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Login Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun register(email: String?, password: String?) {
firebaseAuth!!.createUserWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Registration Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun logOut() {
firebaseAuth!!.signOut()
Timber.i( "firebaseAuth Signed out")
googleSignInClient.value!!.signOut()
Timber.i( "googleSignInClient Signed out")
loggedOut.postValue(true)
errorStatus.postValue(false)
}
private fun configureGoogleSignIn() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(application!!.getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient.value = GoogleSignIn.getClient(application!!.applicationContext,gso)
}
fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
Timber.i( "DonationX firebaseAuthWithGoogle:" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
firebaseAuth!!.signInWithCredential(credential)
.addOnCompleteListener(application!!.mainExecutor) { task ->
if (task.isSuccessful) {
// Sign in success, update with the signed-in user's information
Timber.i( "signInWithCredential:success")
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
} else {
// If sign in fails, display a message to the user.
Timber.i( "signInWithCredential:failure $task.exception")
errorStatus.postValue(true)
}
}
}
}
我的家庭活动
package com.wit.mad2bikeshop.ui.home
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.*
import com.google.firebase.auth.FirebaseUser
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.HomeBinding
import com.wit.mad2bikeshop.databinding.NavHeaderBinding
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.ui.auth.LoggedInViewModel
import com.wit.mad2bikeshop.ui.auth.Login
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
class Home : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var homeBinding: HomeBinding
private lateinit var navHeaderBinding: NavHeaderBinding
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var loggedInViewModel: LoggedInViewModel
private lateinit var headerView : View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeBinding = HomeBinding.inflate(layoutInflater)
setContentView(homeBinding.root)
drawerLayout = homeBinding.drawerLayout
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.bookFragment, R.id.bookingListFragment
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
val navView = homeBinding.navView
navView.setupWithNavController(navController)
initNavHeader()
}
public override fun onStart() {
super.onStart()
loggedInViewModel = ViewModelProvider(this).get(LoggedInViewModel::class.java)
loggedInViewModel.liveFirebaseUser.observe(this, Observer { firebaseUser ->
if (firebaseUser != null)
updateNavHeader(firebaseUser)
})
loggedInViewModel.loggedOut.observe(this, Observer { loggedout ->
if (loggedout) {
startActivity(Intent(this, Login::class.java))
}
})
}
private fun initNavHeader() {
Timber.i("DX Init Nav Header")
headerView = homeBinding.navView.getHeaderView(0)
navHeaderBinding = NavHeaderBinding.bind(headerView)
}
private fun updateNavHeader(currentUser: FirebaseUser) {
FirebaseImageManager.imageUri.observe(this, { result ->
if(result == Uri.EMPTY) {
Timber.i("DX NO Existing imageUri")
if (currentUser.photoUrl != null) {
//if you're a google user
FirebaseImageManager.updateUserImage(
currentUser.uid,
currentUser.photoUrl,
navHeaderBinding.navHeaderImage,
false)
}
else
{
Timber.i("DX Loading Existing Default imageUri")
FirebaseImageManager.updateDefaultImage(
currentUser.uid,
R.drawable.ic_book_nav_header,
navHeaderBinding.navHeaderImage)
}
}
else // load existing image from firebase
{
Timber.i("DX Loading Existing imageUri")
FirebaseImageManager.updateUserImage(
currentUser.uid,
FirebaseImageManager.imageUri.value,
navHeaderBinding.navHeaderImage, false)
}
})
navHeaderBinding.navHeaderEmail.text = currentUser.email
if(currentUser.displayName != null)
navHeaderBinding.navHeaderName.text = currentUser.displayName
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
fun signOut(item: MenuItem) {
loggedInViewModel.logOut()
//Launch Login activity and clear the back stack to stop navigating back to the Home activity
val intent = Intent(this, Login::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
我的书视模型
package com.wit.mad2bikeshop.ui.book
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseUser
import com.wit.mad2bikeshop.firebase.FirebaseDBManager
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.model.BookManager
import com.wit.mad2bikeshop.model.BookModel
class BookViewModel : ViewModel() {
private val status = MutableLiveData<Boolean>()
val observableStatus: LiveData<Boolean>
get() = status
fun addBook(firebaseUser: MutableLiveData<FirebaseUser>,
booking: BookModel) {
status.value = try {
booking.profilepic = FirebaseImageManager.imageUri.value.toString()
FirebaseDBManager.create(firebaseUser,booking)
true
} catch (e: IllegalArgumentException) {
false
}
}
// fun updateBook(booking: BookModel){
// status.value = try {
// BookManager.update(booking)
// true
// } catch (e: IllegalArgumentException) {
// false
// }
// }
}
我的书adapter
package com.wit.mad2bikeshop.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.CardBookBinding
import com.wit.mad2bikeshop.model.BookModel
import com.wit.mad2bikeshop.utils.customTransformation
interface BookListener {
// fun onDeleteBooking(booking: BookModel)
// fun onUpdateBooking(booking: BookModel)
fun onBookingClick(booking: BookModel)
}
class BookAdapter constructor(
private var bookings: ArrayList<BookModel>,
private val listener: BookListener,
private val readOnly: Boolean)
: RecyclerView.Adapter<BookAdapter.MainHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainHolder {
val binding = CardBookBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return MainHolder(binding, readOnly)
}
override fun onBindViewHolder(holder: MainHolder, position: Int) {
val booking = bookings[holder.adapterPosition]
holder.bind(booking, listener)
}
fun removeAt(position: Int) {
bookings.removeAt(position)
notifyItemRemoved(position)
}
override fun getItemCount(): Int = bookings.size
inner class MainHolder(val binding: CardBookBinding,private val readOnly : Boolean) :
RecyclerView.ViewHolder(binding.root) {
val readOnlyRow = readOnly
fun bind(booking: BookModel, listener: BookListener) {
binding.root.tag = booking
binding.booking = booking
binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)
Picasso.get().load(booking.profilepic.toUri())
.resize(200, 200)
.transform(customTransformation())
.centerCrop()
.into(binding.imageIcon)
//
// binding.name.text = booking.name
// binding.phoneNumber.text = booking.phoneNumber
// binding.date.text = booking.date
binding.root.setOnClickListener { listener.onBookingClick(booking) }
// binding.buttonDelete.setOnClickListener { listener.onDeleteBooking(booking) }
// binding.buttonUpdate.setOnClickListener { listener.onUpdateBooking(booking) }
binding.executePendingBindings()
/* binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)*/
}
}
}
我相信问题源于(firebaseimagemanager.imageuri.value.value.tostring.tostring())在我的书adapter上,好像我在timber.i statement.i声明。 t完全返回任何东西。如果我运行timber.i(firebaseimagemanager.imageuri.value.tostring()+“ test”),则仅返回测试。
这是完整项目的链接。
这是一个完整项目 httpps://github.com/foxxxxxxxxx7/mad2bikeshop If i, 还不够清楚,我是新手。
I am trying to get a users profile pic to be displayed beside their booking on a card in my recyclerview. The profile pic is displaying in my nav drawer, a default one for non-google users, or the profile pic of the Google user. However imageUri appears empty when I call it and the images are not being stored in my firebase storage bucket. I have linked my firebase and implemented the relevant SDK.
Here is my model.
@Parcelize
data class BookModel(
// var id : Long = 0,
var uid: String? = "",
var name: String = "N/A",
var phoneNumber: String = "N/A",
var email: String? = "N/A",
var date: String = "",
var bike: Int = 0,
var profilepic: String = "",
/*var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,*/
var pickup: String = "",
var dropoff: String = "",
var price: Double = 20.0,
/*var amount: Int = 0*/
) : Parcelable
{
@Exclude
fun toMap(): Map<String, Any?> {
return mapOf(
// "id" to id,
"uid" to uid,
"name" to name,
"phoneNumber" to phoneNumber,
"email" to email,
"date" to date,
"bike" to bike,
"profilepic" to profilepic,
"pickup" to pickup,
"dropoff" to dropoff,
"price" to price
)
}
}
@Parcelize
data class Location(
var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,
var depot: String = "Waterford"
) : Parcelable
Here is my FirebaseImageManager
package com.wit.mad2bikeshop.firebase
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.lifecycle.MutableLiveData
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.UploadTask
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
import java.io.ByteArrayOutputStream
import com.squareup.picasso.Target
object FirebaseImageManager {
var storage = FirebaseStorage.getInstance().reference
var imageUri = MutableLiveData<Uri>()
fun checkStorageForExistingProfilePic(userid: String) {
val imageRef = storage.child("photos").child("${userid}.jpg")
val defaultImageRef = storage.child("ic_book_nav_header.png")
imageRef.metadata.addOnSuccessListener { //File Exists
imageRef.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
//File Doesn't Exist
}.addOnFailureListener {
imageUri.value = Uri.EMPTY
}
}
fun uploadImageToFirebase(userid: String, bitmap: Bitmap, updating : Boolean) {
// Get the data from an ImageView as bytes
val imageRef = storage.child("photos").child("${userid}.jpg")
//val bitmap = (imageView as BitmapDrawable).bitmap
val baos = ByteArrayOutputStream()
lateinit var uploadTask: UploadTask
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
imageRef.metadata.addOnSuccessListener { //File Exists
if(updating) // Update existing Image
{
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}.addOnFailureListener { //File Doesn't Exist
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}
fun updateUserImage(userid: String, imageUri : Uri?, imageView: ImageView, updating : Boolean) {
Picasso.get().load(imageUri)
.resize(200, 200)
.transform(customTransformation())
.memoryPolicy(MemoryPolicy.NO_CACHE)
.centerCrop()
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,updating)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
fun updateDefaultImage(userid: String, resource: Int, imageView: ImageView) {
Picasso.get().load(resource)
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,false)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
}
My FirebaseAuthManager...
package com.wit.mad2bikeshop.firebase
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.wit.mad2bikeshop.R
import timber.log.Timber
class FirebaseAuthManager(application: Application) {
private var application: Application? = null
var firebaseAuth: FirebaseAuth? = null
var liveFirebaseUser = MutableLiveData<FirebaseUser>()
var loggedOut = MutableLiveData<Boolean>()
var errorStatus = MutableLiveData<Boolean>()
var googleSignInClient = MutableLiveData<GoogleSignInClient>()
init {
this.application = application
firebaseAuth = FirebaseAuth.getInstance()
if (firebaseAuth!!.currentUser != null) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
loggedOut.postValue(false)
errorStatus.postValue(false)
FirebaseImageManager.checkStorageForExistingProfilePic(
firebaseAuth!!.currentUser!!.uid)
}
configureGoogleSignIn()
}
fun login(email: String?, password: String?) {
firebaseAuth!!.signInWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Login Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun register(email: String?, password: String?) {
firebaseAuth!!.createUserWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Registration Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun logOut() {
firebaseAuth!!.signOut()
Timber.i( "firebaseAuth Signed out")
googleSignInClient.value!!.signOut()
Timber.i( "googleSignInClient Signed out")
loggedOut.postValue(true)
errorStatus.postValue(false)
}
private fun configureGoogleSignIn() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(application!!.getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient.value = GoogleSignIn.getClient(application!!.applicationContext,gso)
}
fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
Timber.i( "DonationX firebaseAuthWithGoogle:" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
firebaseAuth!!.signInWithCredential(credential)
.addOnCompleteListener(application!!.mainExecutor) { task ->
if (task.isSuccessful) {
// Sign in success, update with the signed-in user's information
Timber.i( "signInWithCredential:success")
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
} else {
// If sign in fails, display a message to the user.
Timber.i( "signInWithCredential:failure $task.exception")
errorStatus.postValue(true)
}
}
}
}
My Home activity
package com.wit.mad2bikeshop.ui.home
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.*
import com.google.firebase.auth.FirebaseUser
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.HomeBinding
import com.wit.mad2bikeshop.databinding.NavHeaderBinding
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.ui.auth.LoggedInViewModel
import com.wit.mad2bikeshop.ui.auth.Login
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
class Home : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var homeBinding: HomeBinding
private lateinit var navHeaderBinding: NavHeaderBinding
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var loggedInViewModel: LoggedInViewModel
private lateinit var headerView : View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeBinding = HomeBinding.inflate(layoutInflater)
setContentView(homeBinding.root)
drawerLayout = homeBinding.drawerLayout
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.bookFragment, R.id.bookingListFragment
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
val navView = homeBinding.navView
navView.setupWithNavController(navController)
initNavHeader()
}
public override fun onStart() {
super.onStart()
loggedInViewModel = ViewModelProvider(this).get(LoggedInViewModel::class.java)
loggedInViewModel.liveFirebaseUser.observe(this, Observer { firebaseUser ->
if (firebaseUser != null)
updateNavHeader(firebaseUser)
})
loggedInViewModel.loggedOut.observe(this, Observer { loggedout ->
if (loggedout) {
startActivity(Intent(this, Login::class.java))
}
})
}
private fun initNavHeader() {
Timber.i("DX Init Nav Header")
headerView = homeBinding.navView.getHeaderView(0)
navHeaderBinding = NavHeaderBinding.bind(headerView)
}
private fun updateNavHeader(currentUser: FirebaseUser) {
FirebaseImageManager.imageUri.observe(this, { result ->
if(result == Uri.EMPTY) {
Timber.i("DX NO Existing imageUri")
if (currentUser.photoUrl != null) {
//if you're a google user
FirebaseImageManager.updateUserImage(
currentUser.uid,
currentUser.photoUrl,
navHeaderBinding.navHeaderImage,
false)
}
else
{
Timber.i("DX Loading Existing Default imageUri")
FirebaseImageManager.updateDefaultImage(
currentUser.uid,
R.drawable.ic_book_nav_header,
navHeaderBinding.navHeaderImage)
}
}
else // load existing image from firebase
{
Timber.i("DX Loading Existing imageUri")
FirebaseImageManager.updateUserImage(
currentUser.uid,
FirebaseImageManager.imageUri.value,
navHeaderBinding.navHeaderImage, false)
}
})
navHeaderBinding.navHeaderEmail.text = currentUser.email
if(currentUser.displayName != null)
navHeaderBinding.navHeaderName.text = currentUser.displayName
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
fun signOut(item: MenuItem) {
loggedInViewModel.logOut()
//Launch Login activity and clear the back stack to stop navigating back to the Home activity
val intent = Intent(this, Login::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
My BookViewModel
package com.wit.mad2bikeshop.ui.book
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseUser
import com.wit.mad2bikeshop.firebase.FirebaseDBManager
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.model.BookManager
import com.wit.mad2bikeshop.model.BookModel
class BookViewModel : ViewModel() {
private val status = MutableLiveData<Boolean>()
val observableStatus: LiveData<Boolean>
get() = status
fun addBook(firebaseUser: MutableLiveData<FirebaseUser>,
booking: BookModel) {
status.value = try {
booking.profilepic = FirebaseImageManager.imageUri.value.toString()
FirebaseDBManager.create(firebaseUser,booking)
true
} catch (e: IllegalArgumentException) {
false
}
}
// fun updateBook(booking: BookModel){
// status.value = try {
// BookManager.update(booking)
// true
// } catch (e: IllegalArgumentException) {
// false
// }
// }
}
My BookAdapter
package com.wit.mad2bikeshop.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.CardBookBinding
import com.wit.mad2bikeshop.model.BookModel
import com.wit.mad2bikeshop.utils.customTransformation
interface BookListener {
// fun onDeleteBooking(booking: BookModel)
// fun onUpdateBooking(booking: BookModel)
fun onBookingClick(booking: BookModel)
}
class BookAdapter constructor(
private var bookings: ArrayList<BookModel>,
private val listener: BookListener,
private val readOnly: Boolean)
: RecyclerView.Adapter<BookAdapter.MainHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainHolder {
val binding = CardBookBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return MainHolder(binding, readOnly)
}
override fun onBindViewHolder(holder: MainHolder, position: Int) {
val booking = bookings[holder.adapterPosition]
holder.bind(booking, listener)
}
fun removeAt(position: Int) {
bookings.removeAt(position)
notifyItemRemoved(position)
}
override fun getItemCount(): Int = bookings.size
inner class MainHolder(val binding: CardBookBinding,private val readOnly : Boolean) :
RecyclerView.ViewHolder(binding.root) {
val readOnlyRow = readOnly
fun bind(booking: BookModel, listener: BookListener) {
binding.root.tag = booking
binding.booking = booking
binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)
Picasso.get().load(booking.profilepic.toUri())
.resize(200, 200)
.transform(customTransformation())
.centerCrop()
.into(binding.imageIcon)
//
// binding.name.text = booking.name
// binding.phoneNumber.text = booking.phoneNumber
// binding.date.text = booking.date
binding.root.setOnClickListener { listener.onBookingClick(booking) }
// binding.buttonDelete.setOnClickListener { listener.onDeleteBooking(booking) }
// binding.buttonUpdate.setOnClickListener { listener.onUpdateBooking(booking) }
binding.executePendingBindings()
/* binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)*/
}
}
}
I believe the problem stems from the (FirebaseImageManager.imageUri.value.toString()) on my BookAdapter, as if I run a Timber.I statement it doesn't return anything at all. If I run Timber.i(FirebaseImageManager.imageUri.value.toString()+ "test"), it only returns test.
Here is a link to the full project https://github.com/foxxxxxxx7/MAD2bikeshop
Apologies if I wasn't clear enough, I am a novice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我弄清楚了,我不得不在Firebase存储上修改规则。
I figured it out, I had to modify my rules on the firebase storage.