Updated 27 December 2019
Firebase storage provides facility to upload any file like image, video, audio, etc without using server side code.
In this blog, I’ll explain how to create in android application a feature that allows users to upload local image to firebase storage and download the list from the images with the help of firebase database with an example.
Our example app lets user enter file name in a text field and upload image.
Step 1. Create a new project on android studio or open an existing project in which you want to add firebase storage.
Step 2. Add the firebase to the project, follow this link to setup firebase to project. Link: https://firebase.google.com/docs/android/setup
Step 3. Add these dependency to the build.gradle(app)
1 2 3 |
implementation 'com.google.firebase:firebase-database:16.0.4' implementation 'com.google.firebase:firebase-storage:16.0.4' implementation 'com.google.firebase:firebase-auth:16.0.5' |
Step 4. Add the permission to the Androidmanifest.xml
1 |
<uses-permission android:name="android.permission.INTERNET" /> |
1. Firstly image is selected from gallery using file chooser and displayed in ImageView.
2. Before using firebase we have to get its instance and then using the instance create reference to firebase storage app. It can be done by following code.
1 2 |
mStorageRef = FirebaseStorage.getInstance().getReference("uploads") mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads") |
3. Now a child reference is created and using it we call putFile() method to upload image to firebase storage.
4. If image is uploaded successfully then success message is shown otherwise error is shown in toast.
5. To upload the image url to firebase database.
After Getting the image from the application we are now calling then uploadFile() method defined in the main activity to upload image to firebase storage.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
fun uploadFile() { if (imageUri != null) { val fileReference = mStorageRef?.child("${System.currentTimeMillis()}.${getFileExtention(imageUri!!)}") fileReference?.putFile(imageUri!!)?.addOnSuccessListener { task -> Handler().postDelayed({ mBinding.progressBar.progress = 0 }, 200) Toast.makeText(this, getString(R.string.upload_successful), Toast.LENGTH_LONG) .show() fileReference.downloadUrl.addOnSuccessListener{ Log.d("tag",it.toString()) val upload = Upload() upload.name = mBinding.nameEt.text.toString() upload.mImageUrl =it.toString() uploadFileToDatabase(upload) } } ?.addOnFailureListener { Toast.makeText(this, it.message, Toast.LENGTH_LONG).show() } ?.addOnProgressListener { takeSnapshot -> val progress = (100.0 * takeSnapshot.bytesTransferred / takeSnapshot.totalByteCount) mBinding.progressBar.progress = progress.roundToInt() } } else { Toast.makeText(this, getString(R.string.no_file_selected), Toast.LENGTH_LONG).show() } } |
In this firstly we are creating a child on the storage and using the that child reference to upload the image to firebase storage using putFile(imageUri!!). To get Success, failure and progress we using
after successfully uploading the file to firebase storage we will be uploading the image url to the firebase database to do that we getting the name from the editText and image from the fileReference downloadurl and saving it to the firebase database by calling uploadFileToDatabase.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
class MainActivity : AppCompatActivity() { lateinit var mBinding: ActivityMainBinding private val PICK_IMAGE_REQUEST = 1 private var imageUri: Uri? = null private var mStorageRef: StorageReference? = null private var mDatabaseRef: DatabaseReference? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main) mBinding.handler = MainActivityHandler(this) mStorageRef = FirebaseStorage.getInstance().getReference("uploads") mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads") } fun getFileExtention(uri: Uri): String { val contentResolver = contentResolver val mimeType = MimeTypeMap.getSingleton() return mimeType.getExtensionFromMimeType(contentResolver.getType(uri)).toString() } fun uploadFile() { if (imageUri != null) { val fileReference = mStorageRef?.child("${System.currentTimeMillis()}.${getFileExtention(imageUri!!)}") fileReference?.putFile(imageUri!!)?.addOnSuccessListener { task -> Handler().postDelayed({ mBinding.progressBar.progress = 0 }, 200) Toast.makeText(this, getString(R.string.upload_successful), Toast.LENGTH_LONG) .show() fileReference.downloadUrl.addOnSuccessListener{ Log.d("tag",it.toString()) val upload = Upload() upload.name = mBinding.nameEt.text.toString() upload.mImageUrl =it.toString() uploadFileToDatabase(upload) } } ?.addOnFailureListener { Toast.makeText(this, it.message, Toast.LENGTH_LONG).show() } ?.addOnProgressListener { takeSnapshot -> val progress = (100.0 * takeSnapshot.bytesTransferred / takeSnapshot.totalByteCount) mBinding.progressBar.progress = progress.roundToInt() } } else { Toast.makeText(this, getString(R.string.no_file_selected), Toast.LENGTH_LONG).show() } } private fun uploadFileToDatabase(upload: Upload) { val uploadId = mDatabaseRef?.push()?.key.toString() mDatabaseRef?.child(uploadId)?.setValue(upload) } fun openFileChooser() { val intent = Intent() intent.type = "image/*" intent.action = Intent.ACTION_GET_CONTENT startActivityForResult(intent, PICK_IMAGE_REQUEST) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == PICK_IMAGE_REQUEST && resultCode == Activity.RESULT_OK && data != null && data.data != null) { imageUri = data.data Picasso.with(this).load(imageUri).into(mBinding.imageIv) } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="handler" type="com.example.myapplication.handlers.MainActivityHandler" /> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activities.MainActivity"> <androidx.appcompat.widget.AppCompatButton android:id="@+id/choose_file" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/choose_file" android:onClick="@{()->handler.onClickChooseFile()}" /> <EditText android:id="@+id/name_et" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_toEndOf="@id/choose_file" android:layout_marginStart="@dimen/space_normal" android:layout_toRightOf="@id/choose_file" android:hint="Hello World!" android:layout_marginLeft="@dimen/space_normal" /> <androidx.appcompat.widget.AppCompatButton android:id="@+id/upload_file" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="@dimen/spacing_large" android:layout_centerHorizontal="true" android:onClick="@{()->handler.onClickUploadImage()}" android:text="@string/upload" /> <ImageView android:id="@+id/image_iv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/name_et" android:layout_above="@id/progress_bar" android:layout_margin="@dimen/spacing_large" /> <ProgressBar android:id="@+id/progress_bar" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_above="@id/upload_file" android:layout_marginBottom="@dimen/spacing_generic" /> <TextView android:id="@+id/show_upload_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_alignParentBottom="true" android:layout_alignBaseline="@id/upload_file" android:gravity="center" android:textSize="@dimen/text_size_medium" android:padding="@dimen/spacing_large" android:layout_toEndOf="@+id/upload_file" android:layout_toRightOf="@+id/upload_file" android:onClick="@{()->handler.onClickShowImages()}" android:text="@string/show_uploads" /> </RelativeLayout> </layout> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class MainActivityHandler(val mContext: MainActivity) { fun onClickChooseFile() { mContext.openFileChooser() } fun onClickUploadImage() { mContext.uploadFile() } fun onClickShowImages() { mContext.startActivity(Intent(mContext,ImagesActivity::class.java)) } } |
1 2 3 4 5 6 7 8 |
class Upload { @SerializedName("name") @Expose var name:String="no name" @SerializedName("mimageUrl") @Expose var mImageUrl:String="" } |
Create a class having name as ImagesActivity.kt : In this activity we are getting all the list of images saved in the firebase database.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class ImagesActivity : AppCompatActivity() { lateinit var mBinding: ActivityImagesBinding private var mDatabaseReference: DatabaseReference?=null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mBinding = DataBindingUtil.setContentView(this, R.layout.activity_images) mDatabaseReference=FirebaseDatabase.getInstance().getReference("uploads") mDatabaseReference?.addValueEventListener(object: ValueEventListener { override fun onCancelled(error: DatabaseError) { Toast.makeText(this@ImagesActivity,error.message.toString(),Toast.LENGTH_LONG).show() } override fun onDataChange(dataSnapshot: DataSnapshot) { val upload=ArrayList<Upload>() dataSnapshot.children.forEach { val uploaded = Upload() val name = it.child("name").getValue() as String val imageUrl = it.child("mimageUrl").getValue() as String uploaded.name = name uploaded.mImageUrl = imageUrl upload.add(uploaded) } val adapter=ImageListAdapter(this@ImagesActivity,upload) mBinding.recyclerView.adapter=adapter } }) } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> </data> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activities.ImagesActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/> </RelativeLayout> </layout> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class ImageListAdapter(val mContext: ImagesActivity, val imageList: List<Upload> ): RecyclerView.Adapter<ImageListAdapter.ViewHolder>() { class ViewHolder(val binding: ImageItemBinding) : RecyclerView.ViewHolder(binding.root) { } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.image_item,parent, false)) } override fun getItemCount(): Int { return imageList.size } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.binding.nameTv.text=imageList[position].name Picasso.with(mContext).load(imageList[position].mImageUrl).into(holder.binding.imageIv) } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="data" type="com.example.myapplication.models.Upload" /> </data> <androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_margin="@dimen/spacing_generic"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/name_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/spacing_generic" /> <ImageView android:id="@+id/image_iv" android:layout_width="@dimen/spacing_huge" android:layout_height="@dimen/spacing_huge" android:layout_margin="@dimen/spacing_generic" /> </LinearLayout> </androidx.cardview.widget.CardView> </layout> |
. . . . . . .
That’s all for now, I hope this blog have helped you, Comment below if you have any queries related to above android upload image to firebase storage example.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.