DOUG STEVENSON: Welcome, Android devs, to another Firecast.
I'm Doug Stevenson.
And this time I'm going to show you
how to use Firebase Storage to upload an image
file from an app and get a web bureau
you can use to download it.
Firebase Storage is a robust, secure, and scalable solution
for storing files associated with your app.
In order to get started with it, you'll
need to get the Firebase SDK integrated into your app.
If you haven't done that yet, go check out this other video
first, where I'll walk you through the creation
of a new project.
And remember that the latest version of the Firebase SDKs,
at the time of this recording, is 9.6.1.
OK.
I already have an app set up here.
So I'm going to use that to work with Firebase Storage.
Let's see what that app looks like.
The app draws a Firebase logo on a light blue background.
Then when I type text into this edit text widget,
it overlays that text over the image, kind of like a meme.
And there's an Upload button here,
which doesn't seem to do anything at the moment.
So what we're going to do here is make this button upload
the image on screen to Firebase storage.
Before we get started, you should
know that Firebase Storage is meant to work
with Firebase Authentication.
Typically, you only want people logged into your app
to upload files.
This prevents random people from dumping things
into your project's storage bucket.
But to make this video short and sweet,
I'm going to skip the authentication step
and get straight to the uploads.
To do that I'm going to have to change the default security
role, so that writing to my project storage bucket
doesn't require authentication.
In the Firebase console for my project,
I'm going to select Storage on the left.
This shows me my initially empty storage bucket.
I'll switch to the Rules tab, which shows me the default
rules for new projects.
These rules restrict reading and writing
to only authenticated users.
You don't have to understand rules right now,
but I'll show you how to disable them
so you can experiment with reading and writing
without having to use authentication.
But before I do that, you need to know this.
What I'm about to tell you isn't safe for your app all the time.
This is for development only.
And when you're done experimenting with storage,
you want to enable the security rules again, and eventually
use Firebase Authentication to make sure
only authenticated users can write to your storage bucket.
OK.
Back to the console.
So the quickest way to disable the security rules
is to simply change the read and write condition
for the entire bucket to true.
I'll also comment out the remainder
of the line to remind me what was there before.
After I push the Publish button here,
I'll be able to test writing to my bucket
without authentication.
Now in Android Studio the first thing I'll need to do
is add the Firebase Storage compile dependency
to my apps build.gradle.
The latest version right now is 9.6.1.
This gives us access to the Firebase Storage client API.
OK.
Let's take a look at the source code for this apps activity.
There is already code in OnCreate
that finds and initializes the views in my activities view
hierarchy.
Also, I've already got a click handler for the Upload button.
In that handler, I'm using Android's APIs
to get a bitmap of the view containing the image to upload.
Then I'm compressing that image bitmap to PNG format.
And finally, I've got the raw pixels
of the image in a byte array.
So what I'd like to do here is also upload that image
to Firebase Storage.
So I'll show you how to do that.
The first thing to add is a reference to the Firebase
Storage singleton instance.
I'll store that at a private member variable
near the top of the class.
Next, I need to figure out the full path
name of the image file to store in my project storage bucket.
I'm going to store these images in a directory called
firememes.
And the name of the file will be unique by using a random UUID.
And as is typical for files in PNG format,
I'll add the file extension PNG.
After I have a path name, I'll get a storage reference
to that path using the storage API.
This storage reference object is my main hook
into dealing with this image on Firebase Storage.
I'll use it to upload the image to my project storage bucket
at the path I've given.
I'll do one other thing as well.
I'll attach a piece of custom metadata to the image
by using this builder provided by the SDK.
I'll call this field text, and it
will contain the text that's overlaid on the logo.
With these two objects in hand, I can kick off an upload simply
by calling the put bytes method on the storage reference,
and pass it the byte array to upload and the metadata
to go with it.
This method returns an object called
an upload task which lets you monitor
the status of the transfer.
At this point, we actually don't have to read any more code.
The Firebase Storage SDK will handle the upload just fine.
However, we probably want to let the user of the app
know when the upload is complete.
So we'll use the upload task object for that,
and display a progress spinner to indicate
that the upload is in progress.
Let's take a look at that.
This app already has a progress bar widget,
styled to look like a spinner, that's
initially hidden below the Upload button,
as you can see here.
So in my upload button click handler,
I'll add a line of code to make that visible
when the upload starts.
I'll also disable the Upload button
to prevent the user from uploading again right away.
To know when the upload finishes,
I'll need to register a success listener with the upload task.
I have Android Studio generate most of that for me.
Notice that I'm passing the activity
instance as the first argument.
This scopes the listener to the activity instance,
so the listener won't remain attached if the activity stops
before the upload is complete.
This is important to prevent leaking of your activity
object.
To learn more about the task API that you'll use with Firebase,
you can check out the documentation here.
And there's also a more detailed blog series that starts here.
Now when the upload task does complete,
the OnSuccess callback will execute,
and get past a task snapshot object that
describes the results.
In the success callback, I'll hide the progress bar
and enable the Upload button again.
One final thing I'll do here is get the download URL
from the task snapshot, and show that in a hidden text
view, which I'll make visible.
The download URL is an HTTPS-type URL
that can be used to download the image,
and we'll see that work in a little bit.
OK.
Let's give this app a run, and see how it goes.
I'll type in my text, then click the Upload button,
and we get some feedback that the upload is happening.
Then when it's done, I see the full download URL
that anyone can use to view the image.
If I click it here in the emulator,
it'll launch a web browser app, and that will download and show
the image.
Now if I go back to the Firebase console and refresh
the storage page, you can now see the firememes directory.
And inside that is the image I just uploaded.
On the right, we can see some information about the file.
Because the file ended in png, its content type was assumed.
And in the other Metadata section,
we see the custom metadata containing the text I typed.
In the File Location section, it will show me
the exact same download URL I clicked in the app.
If, for some reason, I don't want this file
to have a public download URL, I can
revoke the token associated with the link,
with the revoke button.
This will stop that URL from ever working again.
I can also add a whole new download URL
by clicking Create New download URL.
All right those are the basics for using Firebase Storage
to upload a file and make use of its download URL
to access its contents.
There's a whole lot more to learn about Firebase Storage,
so read through the documentation right here.
Be sure to learn about uploading data from an input stream,
downloading files, deleting files, managing ongoing uploads
and downloads, and how to handle errors from any of those tasks.
Oh, and don't forget to learn more
about security and validation rules to protect your storage.
In particular, as an Android developer,
you should pay special attention to handling activity lifecycle
changes during an upload or download.
The SDK gives you a way to reattach to an ongoing upload
and download task so UI can pick up
where it left off if your activity is interrupted
for any reason.
And that's all we have time for in this Firecast.
Why don't you give Firebase Storage a try?
Let me know how it works for you.
You can use the comments below, or you
can message me directly @CodingDoug on Twitter.
See you next time.