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: