Search code examples
androidkotlinfirebase-realtime-databasefirebase-storage

Firebase Caching in Jetpack Compose


@HiltAndroidApp
class MelonFeedApp: Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseDatabase.getInstance().setPersistenceEnabled(true)
    }
}

MelonFeedApp.kt

class UserRepositoryImpl @Inject constructor(
    private val db: FirebaseDatabase,
    private val auth: FirebaseAuth
): UserRepository {

    private lateinit var userRef: DatabaseReference

    init {
        auth.currentUser?.let {
            userRef = db.getReference("users/${it.uid}")
            userRef.keepSynced(true)
        }
    }

    // methods
}

UserRepositoryImpl.kt

@HiltViewModel
class ProfileViewModel @Inject constructor(
    context: Context,
    private val userRepository: UserRepository,
    private val auth: FirebaseAuth
) : ViewModel() {

    private val _profilePic = MutableLiveData<Bitmap?>()
    val profilePic: LiveData<Bitmap?> = _profilePic

    init {
        viewModelScope.launch {
            val imageData = getUserProfileImage()
            if (imageData != null) {
                val bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.size)
                _profilePic.value = bitmap
            } else {
                val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.profilepc)
                _profilePic.value = bitmap
            }
        }
    }


    fun updateProfilePic(bitmap: Bitmap) {
        _profilePic.value = bitmap
    }

    private suspend fun getUserData(fieldName: String) {
        return withContext(Dispatchers.IO) {
            try {
                userRepository.getCurrentUserData(fieldName)
            } catch (_: Exception) {

            }
        }
    }
    private suspend fun getUserProfileImage(): ByteArray? {
        val storageReference = FirebaseStorage.getInstance().reference
        val profileImageReference = storageReference.child("profile_images/profilePicture_${auth.currentUser?.uid}")
        return profileImageReference.getBytes(2 * 1024 * 1024 * 1024L).await()
    }
}

ProfileViewModel.kt

I have enabled diskPersistense in MelonFeedApp.kt and I've turned on keepSynced in UserRepositoryImpl.kt but still If I turn off my network connection then it doesn't load the profile picture.

Please help me with Firebase Caching. I've been trying it for a few days now but I still can't figure it out.


Solution

  • If I turn off my network connection then it doesn't load the profile picture.

    If you want to cache the data as well as the pictures, then you have to use a library for that. Since you're using Jetpack Compose, a good option would be to use Coil which is:

    An image-loading library for Android backed by Kotlin Coroutines.

    And can be used with Jetpack Compose by adding the following dependency:

    implementation("io.coil-kt:coil-compose:2.6.0")