Build a personal Markdown notebook with Firebase Storage

Build a personal Markdown notebook with Firebase Storage

my first single page application online

Brief at a glance

In a previous post, Firebase realtime database was used to build a comment system for my site. Indeed, all the Firebase tools are such easy to use, and I’ve had a pleasant experience with them.

Dig it deeper and comes out the single page app – an online Markdown Notebook, just try it out!

Okay, let’s start to have a glance on the online notebook.

Note that the Firebase Realtime Database or Cloud Firestore itself is capable of storing the Markdown contents as plain string. However, consider the storage limits (1GB vs 5GB) for a Firebase Spark Plan (free), it’s better to use Storage to store large quantity of markdown contents. More details about Firebase pricing here:

Because of the 5GB limitation, I put the word personal in the title of this post. But everyone else is welcome to play around with it. It’s hosted with Firebase Hosting, you can download the repo at to deploy your own copy. and Semantic UI

OK, let me explain a little bit more about it - Markdown Notebook. The UI is based on Semantic. At the very beginning, I am just playing around with the UI library, but later I found it’s interesting to do something more with it. That’s why I choose the, it’s appearance is consistent with the Semantic UI:

appearance of Firenote

What’s more, is a well designed open source markdown editor and not difficult to use. I just extend its ability with cloud storage.

The Notebook structure

In this Markdown Notebook, the Firebase realtime database is used to record the notes information – notebook name, note name, and the update time. Each time when the user was logged in (only Google account authentication used here), it will pull notes and notebook information from Firebase database without download the file (markdown contents) from Firebase Storage.

The markdown contents are stored as files in the Firebase Cloud Storage using the same structure as the realtime database. Every note must sit into a notebook and the Markdown file loads into the same notebook folder.

Notes structure

Save and delete the note

Just as the same operation in Firebase database, we should first set a .ref() to the note.

Since Firebase authentication is used, the data and files are put under specific user’s space, and set the rules that only the user can read and write:

var userID;
var userName;

firebase.auth().onAuthStateChanged(function(user) {
    if (user) {
        userName = user.displayName;
        userID = user.uid;

var databaseRef = firebase.database().ref().child(userID);
var storageRef =;

var noteName = "some given name";

// just for showing the idea
// design your detailed data structure
var notedataRef = databaseRef.child("notebookname/" + noteName);
var notefileRef = storageRef.child("notebookname/" + noteName);

Whenever you click save (or press Ctrl+S), put the textarea’s content into a markdown file (text/plain) and upload it to Firebase storage:

var noteContent = $("#noteContent").text();
var file = new Blob([noteContent], { type: "text/plain" });

var uploadTask = notefileRef.put(file);

In this process, check whether the file exists in the Firebase storage. If it already exists, just simply delete it then upload it again as an update operation.

For deleting the notes, I found that I didn’t need to delete the notebook as Firebase simply remove empty database node and empty storage folder. Thus, just delete the note itself is OK, no need to care about deleting empty folders. Notice that in the database, you should use .remove(); but in the storage, use .delete() instead for deleting node/file.

Download the file from Firebase storage

It’s easy to put (upload) files into the Firebase Storage, but when I’m trying to download them, the CORS (Cross-Origin Resource Sharing) settings stopped the operation.

If you are going to build your own version of the web app, you should follow this Configuring CORS on a Bucket to configure CORS using gsutil for your domain.

And then download the markdown file and get the content with jQuery (better to use Fetch API in the future…):

notefileRef.getDownloadURL().then(function(url) {
    var jQxhr = $.get(url, function(data){;
}).catch(function(error) {
// Handle any errors

The above process is triggered by click the note’s name in the “Open” menu.


At present, it involves lots of bugs. I believe you can make it even better. But be honestly, there’s lots of online Markdown editor in the market, the most possibility of this one is for personal use and customise it that fit your demands.

Ads by Google


Frank Lin

Hey, there! This is Frank Lin (@flinhong), one of the 1.41 billion . This 'inDev. Journal' site holds the exploration of my quirky thoughts and random adventures through life. Hope you enjoy reading and perusing my posts.


Hands on IBM Cloud Functions with CLI



Hands on IBM Cloud Functions with CLI

IBM Cloud CLI allows complete management of the Cloud Functions system. You can use the Cloud Functions CLI plugin-in to manage your code snippets in actions, create triggers, and rules to enable your actions to respond to events, and bundle actions into packages.

Using Liquid in Jekyll - Live with Demos

Web Notes


Using Liquid in Jekyll - Live with Demos

Liquid is a simple template language that Jekyll uses to process pages for your site. With Liquid you can output complex contents without additional plugins.