firebase-kotlin-sdk icon indicating copy to clipboard operation
firebase-kotlin-sdk copied to clipboard

How to download files using storage?

Open SirFilbido opened this issue 1 year ago • 7 comments
trafficstars

I have implemented the storage library but I am having difficulty downloading files.

In my case, I have to download .zip files in the commonMain package.

Does the SDK currently have this type of implementation? If not, would I have to implement it on the native side to then use it in the shared environment?

SirFilbido avatar Jun 11 '24 21:06 SirFilbido

Im not a maintainer or anything but i have been working on some storage improvements. There is currently no implementation for this.

You can add the functionality by updating the expected class in commonMain and then you can use the native SDKs to provide the actual implementations.

I don't know what kind of files you want to download but you can also access the download url of a reference. That way you can use your http client to download these files as long as this functionality is not available yet.

BasBuijsen avatar Jun 12 '24 12:06 BasBuijsen

Thanks for the tips @BasBuijsen , I'll try to implement the download via the file's URL. In my case, they are .zip files

But I'm having another problem and I don't know if the SDK supports this. I have some different databases in the storage. I need to configure the address that is not in the google-services.json file.

On Android I can do it like this

val storage = Firebase.storage(BuildConfig.BUCKET_SINC)

How would I do this in Firebase SDK?

SirFilbido avatar Jun 13 '24 14:06 SirFilbido

@SirFilbido as far as i can see there is no support for this yet.

BasBuijsen avatar Jun 14 '24 12:06 BasBuijsen

@SirFilbido i had some time to spare so i created the getters for Firebase storage with a custom url.

BasBuijsen avatar Jun 20 '24 13:06 BasBuijsen

Great news, thanks @BasBuijsen.

SirFilbido avatar Jul 01 '24 13:07 SirFilbido

You can download files using Ktor HTTP client. Here's a minimal snippet that combines GitLive's Firebase Storage and Ktor, to download a file:

val link = Firebase.storage.reference.child(path).getDownloadUrl()

val client = HttpClient(CIO) {
    install(Logging) {
        level = LogLevel.INFO
    }
}

client.prepareGet(url = Url(link)).execute { httpResponse ->
                val channel: ByteReadChannel = httpResponse.body()

                while (!channel.isClosedForRead) {
                    val packet = channel.readRemaining(DEFAULT_HTTP_BUFFER_SIZE.toLong())
                    while (!packet.isEmpty) {
                        val bytes = packet.readBytes()
                        
                        //todo: do something with the received bytes, for example, you can add them to a mutable byte array
                    }
                }
            }

You can extend this example by using kotlinx.io which allows you to write to platform-specific files from common code using sink()

yuroyami avatar Jul 14 '24 06:07 yuroyami

Hi,

commonMain:

expect suspend fun getFile(path: String): Result<String> 

androidMain:

private const val ONE_MEGABYTE: Long = 1024 * 1024

actual suspend fun getFile(path: String): Result<String> {
    return try {
        Firebase.storage.android.getReference(path).getBytes(ONE_MEGABYTE).await().let { Result.success(String(it)) }
    } catch (e: Exception) {   
        Result.failure(e)
    }
}

iosMain:

private const val ONE_MEGABYTE: Long = 1024 * 1024

@OptIn(ExperimentalForeignApi::class)
actual suspend fun getFile(path: String): Result<String> {
    return withTimeoutOrNull(1000) {
        suspendCancellableCoroutine { cont ->
            Firebase.storage.ios.referenceWithPath(path).dataWithMaxSize(ONE_MEGABYTE) { data, error ->
                if ((error != null && error != nil) || data == null)
                    cont.resume(Result.failure(Exception("File not found")))
                else
                    cont.resume(Result.success(data.toByteArray().toKString()))
            }
        }
    } ?: Result.failure(Exception("Timeout"))
}

dogeweb avatar Aug 23 '24 21:08 dogeweb

I believe the original issue is solved now

nbransby avatar Sep 12 '24 04:09 nbransby