What is the best way to store history of data in Firebase Realtime Database?

Viewed 722

There is an app I'm building using Firebase Realtime Database. Users of this app will be able to create a post and edit it anytime they want. Also, they're allowed to access all versions of the post, but they'll get the latest version by default. I've got this so far:

Realtime Database-root
   |
   --- posts
        |
        --- postId
                 |
                 --- versionId
                 |           |
                 |           --- uid
                 |           |
                 |           --- title
                 |           |
                 |           --- date
                 |           
                 --- versionId
                             |
                             --- uid
                             |
                             --- title
                             |
                             --- date

However, I'm afraid that this is the best way to go. Could this approach be improved considering cost, scalability, security and performance?

1 Answers

Since the RTDB costs $5 per GB stored I would recommend that you use Google Storage as a cheap datastore to store your versions.

What that means is your database should store posts like this:

Realtime Database-root
   |
   --- posts
        |
        --- postId
                 |
                 --- uid
                 |
                 --- title
                 |
                 --- date
   --- postsVersions
        |
        --- postId
                 |
                 --- version1Id: true
                 |
                 --- version2Id: true

version1Id and version2Id reference JSON documents stored in Google Storage.

Workflow

  1. User creates the initial post and the database entry is made.

  2. User makes changes and saves them to the RTDB, overwriting the previous version in /posts.

  3. A Cloud Function that is triggered on the onUpdate() event on /posts/{postId} takes the previous version and saves it to Google Storage as https://storage.google.com/<bucket>/<postId>/<version1Id>.json and saves that versionId to /postsVersions.

  4. If the user deletes the version1Id key from that /postsVersions, a Cloud Function monitoring the onDelete() event on /postsVersions/{postId} should delete that JSON file from Google Storage.

  5. Finally if the user would like to load a previous version of a post, they make a simple HTTPS request to retrieve the JSON file from Google Storage and then they update /posts with the previous version.

Security

You should make sure that your version IDs are unguessable and non-sequential and you can then simply provide blanket access to the bucket using IAM permissions for all authenticated users. For more granular control where users can't potentially access other users' versioned posts, a non-public bucket and an API endpoint that generates a signedURL would be simple to implement.

Related