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: https://firebase.google.com/pricing.
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 https://github.com/flinhong/firenote to deploy your own copy.
Editor.md 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 editor.md, it’s appearance is consistent with the Semantic UI:
What’s more, editor.md 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.
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 = firebase.storage().ref().child(userID);
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){
mainEditor.cm.setValue(data);
});
}).catch(function(error) {
// Handle any errors
});
The above process is triggered by click the note’s name in the “Open” menu.
Further
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.