1

I have an app to create reports with some data and images (min 1 img, max 6). This reports keeps saved on my app, until user sent it to API (which can be done at the same day that he registered a report, or a week later).

But my question is: What's the proper way to store this images (I'm using Realm), is it saving the path (uri) or a base64 string? My current version keeps the base64 for this images (500 ~~ 800 kb img size), and then after my users send his reports to API, I deleted this base64 hash.

I was developing a way to save the path to the image, and then I display it. But image-picker uri returned is temporary. So to do this, I need to copy this file to another place, then save the path. But doing it, I got (for kind of 2 or 3 days) 2x images stored on phone (using memory).

So before I develop all this stuff, I was wondering, will it (copy image to another path then save path) be more performant that save base64 hash (to store at phone), or it shouldn't make much difference?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38

1 Answers1

3

I try to avoid text only answers; including code is best practice but the question about storing images comes up frequently and it's not really covered in the documentation so I thought it should be addressed at a high level.

Generally speaking, Realm is not a solution for storing blob type data - images, pdf's etc. There are a number of technical reasons for that but most importantly, an image can go well beyond the capacity of a Realm field. Additionally it can significantly impact performance (especially in a sync'ing use case)

If this is a local only app, storing the images on disk in the device and keep a reference to where they are (their path) stored in Realm. That will enable the app to be fast and responsive with a minimal footprint.

If this is a sync'd solution where you want to share images across devices or with other users, there are several cloud based solutions to accommodate image storage and then store a URL to the image in Realm.

One option is part of the MongoDB family of products (which also includes MongoDB Realm) called GridFS. Another option is a solid product we've leveraged for years is called Firebase Cloud Storage.

Now that I've made those statements, I'll backtrack just a bit and refer you to this article Realm Data and Partitioning Strategy Behind the WildAid O-FISH Mobile Apps which is a fantastic article about implementing Realm in a real-world use application and in particular how to deal with images.

In that article, note they do store the images in Realm for a short time. However, one thing they left out of that (which was revealed in a forum post) is that the images are compressed to ensure they don't go above the Realm field size limit.

I am not totally on board with general use of that technique but it works for that specific use case.

One more note: the image sizes mentioned in the question are pretty small (500 ~~ 800 kb img size) and that's a tiny amount of data which would really not have an impact, so storing them in realm as a data object would work fine. The caveat to that is future expansion; if you decide to later store larger images, it would require a complete re-write of the code; so why not plan for that up front.

Jay
  • 34,438
  • 18
  • 52
  • 81
  • Jay, first thank you very much for your time and attention. Your answer helped much more than I asked, and I'll keep it for my future projects too. But I got just one more question, when you mention that I can store the images as data objects (because they are small), you mean save their base64 hash into Realm? – Gabriel Porcher Apr 27 '21 at 15:01
  • @GabrielMelloPorcher You got it! I code in Swift so I generically used the word 'Data' as Realm Supports ObjC NSData (Swift Data) objects. So an image would be encoded base64 like this `let base64String = someImage!.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)` but the concept applies to all platforms. Again though - you can 'get away with it' because the image sizes are so small; as long you as you keep them that way it should be fine. Oh - if my answer helped, be sure to [Accept it](https://stackoverflow.com/help/someone-answers) so it can help others. – Jay Apr 27 '21 at 15:19