Add Firebase to Android (Setup Firebase on Android)
Setup Storage
Goto Firebase Console -> Storage -> Get started
.
By default, your rules allow all reads and writes from authenticated users.
// Only authenticated users can read or write to the bucket
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
If you are not using Firebase Auth yet, you need to make the access public (I believe this is a security risk, and recommended to implement Firebase Auth as soon as possible).
// Anyone can read or write to the bucket, even non-users of your app.
// Because it is shared with Google App Engine, this will also make
// files uploaded via GAE public.
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
NOTE: Like Firestore, security rules only apply to client (Android, iOS, Web) while server-side code can access everything.
You might want to read up on storage classes and locations later.
Android
Dependecies
dependencies {
// implementation 'com.google.firebase:firebase-storage:19.1.0'
// using kotlin implementation
implementation 'com.google.firebase:firebase-storage-ktx:19.1.0'
}
Upload
suspend fun uploadPhoto(uid: String?, file: File, name: String, mimeType: String?): String { val storage = FirebaseStorage.getInstance() val storageRef = storage.reference val fileRef = if (uid == null) storageRef.child("public/images/$name") else storageRef.child("user/$uid/images/$name") var uri = Uri.fromFile(file) // TODO: handle exception // await - kotlinx-coroutines-play-services val metadata = mimeType?.let { StorageMetadata.Builder() .setContentType(mimeType) // .setCustomMetadata("ref", "test") .build() } val task = if (metadata != null) { fileRef.putFile(uri, metadata).await() } else { fileRef.putFile(uri).await() } // val task = fileRef.putStream(stream).await() // task.metadata.reference == fileRef val url = fileRef.downloadUrl.await().toString() // url can be used to reconstruct StorageReference // val ref = storage.getReferenceFromUrl(url) // Timber.d("name=${ref.name}, path=${ref.path}, bucket=${ref.bucket}, same=${fileRef == ref}") return url}
You might want to store the URI path to access the storage object.
val StorageReference.uriString: String // gs://bucket/images/stars.jpg get() = "gs://$bucket$path"val id = fileRef.uriStringval ref = storage.getReferenceFromUrl(id)
NOTE: Using Kotlin Coroutines and kotlinx-coroutines-play-services.
Security Rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// by default, only authenticated user ca read and write
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
// anyone can read and write at /public
match /public/{allPaths=**} {
allow read, write;
}
// only owner can read and write at /user/{userId}
// Files look like: "user/<UID>/path/to/file.txt"
match /user/{userId}/{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
}
}
NOTE: You might want to resize image before upload.
References: