10

I need to add JPEG images to Firestore DB records. My preferred way would be in a blob as I have used in SQLite records. I ran into some problems trying this.

This is my best try so far:

public Blob getImage() {
    Uri uri = Uri.fromFile(new
File(mCurrentPhotoPath));
    File f1 = new File(mCurrentPhotoPath);
    URL myURL = null;
    try {

        myURL = f1.toURI().toURL();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }

    Bitmap bitmap = null;

    BitmapFactory.Options options = new
BitmapFactory.Options();
    options.inPreferredConfig =
Bitmap.Config.ARGB_8888;
    try {
        if (myURL != null) {
            bitmap =
BitmapFactory.decodeStream(
myURL.openConnection().getInputStream());
            String wBlob =
encodeToBase64(bitmap,
 Bitmap.CompressFormat.JPEG, 100);
       blob = fromBase64String(wBlob);
}


    } catch (java.io.IOException e) {
        e.printStackTrace();

    }
    return blob;
}

My problem is in the line:

blob = fromBase64String(wBlob);

I also have a problem with passing a blob to the class that sets the record:

intent.putExtra("blobImage",  blob );
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
rosey
  • 141
  • 1
  • 3
  • 9

1 Answers1

40

As a general rule, unless you're storing fairly small icons, I'd say, "Don't do this."

While you can store native binary data in Cloud Firestore you're going to run up against some limits in the database, specifically, a single document can't be more than 1 MB large. (You don't really need to Base64-encode your image.)

Instead, I would store the images themselves in Cloud Storage for Firebase and then just keep the download URLs in Cloud Firestore. Cloud Storage is approximately 7x cheaper in terms of storage costs, has much larger limits in terms of maximum file size, and by grabbing these download URLs, you can take advantage of third-party libraries like Picasso and Glide that can manage the image downloading for you, while also adding nifty features like memory or disk caching or showing placeholder graphics.

You might want to check out the "Getting Started with Firebase Storage on Android" video for more information.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Todd Kerpelman
  • 16,875
  • 4
  • 42
  • 40
  • 1
    Hi Todd. This is a Cloud Firestore question, rather than RTDB. Does your answer still stand for this, also? I'm storing base64 encoded files in Cloud Firestore for one of my apps, as it allows better security rules control than Cloud Storage for Firebase. – Jason Berryman Mar 13 '18 at 22:26
  • Sorry -- just updated my answer for Cloud Firestore. (Long story short, I'd still recommend Cloud Storage for images. It's less of a pricing concern, but more of a "You will probably run up against the maximum document size" concern.) – Todd Kerpelman Mar 13 '18 at 22:31
  • 1
    Thanks, Todd. For the data that I'm working with, the 1Mb limit is never exceeded. I'm hoping that one day, Cloud Storage Security Rules will be able to query against values stored in the RTDB / Cloud Firestore. – Jason Berryman Mar 13 '18 at 22:36
  • Thank you for the good suggestion. I currently store the images in Firebase storage and the path in the document. It works very well. I thought if I could get away the blog it would be more compact but my intuition was exactly what you suggested. – rosey Mar 13 '18 at 23:34