Tutorial:

Build a Forum Application

Create a simple app with Framework7 and Firebase

Melinda Magyar
The Web Tub

--

As the title suggests, today we will build a simple forum application with a combination of Framework7 and Firebase by using Monaca.

In the first half of the article, we will explain the details of the application. In the second half, we start developing it.

Technologies and libraries used

In Monaca, select the Core Tab View of Framework7 in Framework Templates, Javascript and create a new project.

Application Outline

Thread List Screen
This is the home page of our application. It displays a list of threads.

Sign In/Sign Up Screen
Tap the 👤 icon at the right corner of the toolbar to bring up an input dialog for signing in with an already existing user account. Or you can create one if you click on the Sign Up button.

The two pages have very similar design elements.

New Thread Input Dialog
Log in with an existing account and tap on the + icon next to the Forum Threads text. The following information is requested from the user:

  • Thread Title
  • Thread Description
  • Picture

Thread Details Screen
Tap on an existing thread to display the thread details. Here you will see the content and the comments for that thread. You can even enlarge a comment picture with a tap on it.

New Comment Input Dialog
Tap the 💬 icon at the right bottom of the screen to display a dialog for writing a new comment. The following information is requested from the user:

  • Comment Text
  • Image (optional)

Data Permissions
Anyone can view the threads and comments, however only logged in users can create new threads or add any new comments. Each user who created a thread or a comment has delete permission and able to delete their created content only.

Development
CSS

Before we jump into it, add the following CSS styles to the app.css and icons.css file, so that you don’t have to bother with these later on.

www/css/app.css
www/css/icons.css

Firebase
Create a new project at Firebase. After you set up the project open the Firebase Project Settings. There you will find the necessary code for the configuration and initialization of Firebase. (Step by step instructions for first-time users here.)

Then create a new js file as config.js under the www/js folder and copy-paste the code from the Firebase Project Settings. Now, let’s also create two references under the initialization. We need these to use the Firebase Authentication and Storage features later on in our code.

One last thing; in your index.html before the closing </body> tag add the Firebase libraries for the App, Authentication, Firestore and Storage. You can find the latest SDK libraries here, under the Available libraries, Available Firebase JS SDKs (from the CDN) section.

index.html
The www/index.html is displaying our main page in the application. It has the following components: Navbar, Scrollable Page Content, Login Pop Up.

Each element is embedded in the view-main in the following order;

In the code, you can see that there is another view initialized for the Login Pop Up. We will use this view-popup to show the contents of register.html in the login-popup window when the user clicks on the Sign Up button.

register.html
In the www/pages folder, we will create a register.html. It will contain our HTML code for the registration page. The structure of the page is very similar to the Login Pop Up.

thread.html
Create a thread.html in the www/pages folder. This page will display the details of each thread. It has the following HTML:

routes.js
Now that we have our basic HTML for each page, we have to configure and add the routes for each page and component to the routes.js in the www/js folder like this:

Authentication
Our next focus is user authentication and we will use Firebase’s service to perform authentication in our Forum App. If you haven’t done it yet, please enable Authentication in the previously created Firebase project.

Then create the auth.js in the www/js folder. It will contain everything in connection with the authentication process, such as:

  • Sign Up
  • Sign In
  • Sign Out
  • Listener for Auth Status Changes
  • Get Threads Data

Let’s go through each functionality one by one.
For better understanding, we added some comments to each code snippet.

Sign Up/Registration
Sign In/Login

The Sign Out/Logout is very short. It requires only two lines to do it.

The function, which listens for any auth status change is also short, yet useful because we are displaying different elements in the layout according to the user status.

To get the necessary data from the database for the threads we will use the getThreads() function. Inside of it, there’s an asynchronous call, where we will get a snapshot of the current database. We will use that snapshot in the setUpThreads() function later.

Cool! We’re done with everything so far that is connected to authentication. Now, add the essential pieces to the index.html, register.html, thread.html — after the closing </html> or </template> tags.

In the index.html we will call the getThreads(). The function under the call will guarantee that every time the page is in init state, it will reloading its content.

index.html
register.html

In the thread.html we’ll rely on the onAuthStateChanged() again to toggle the new comment button with it.

Functionality
From now on we’ll take a look at all the other functionalities in the app.js.

f7
Since we are using Framework7, you should have something very similar from the start in your app.js to initialize f7.

UI
Here is the setUpUI()function. As the name suggests, it is displaying or hiding some elements according to the user status.

Images
We have three main functions responsible for uploading, displaying and deleting images in the threads and comments. In two of the three cases (display, delete), we have to retrieve the data from the Firebase Storage and manipulate it. When we are uploading, it’s different.

In upload, you create a reference to the full path of the file, including the file name. Once you’ve created an appropriate reference, you then call the put() method. put() takes the file and uploads it to the Firebase Storage. After the upload is finished, we are calling either the getThreads() or the setUpComments() function.

For displaying any images, we have to download the files from the Storage. In order to do that, create a Cloud Storage reference to the file. Then by calling getDownloadURL() method on the reference, we’ll get the download URL and set it to the src or the backgroundImage of a selected element to display it.

The deletion is really easy. It starts the same way, with creating a reference to the file. Then call the delete() method on that reference.

Threads
To create a new thread, to display the list of threads on the home page and to show the thread details we have three different functions.

To add a new document to the Firestore threads collection we will use the add() , then we’ll upload the thread’s picture too with uploadImage().

To display the threads on the home page we have to get multiple documents from the threads collection with forEach and chain each element together in the html variable. After the forEach finished its execution, we’ll add the html (which now has x number of li elements) to the threadsList .

When a user clicks on a thread on the home page, we are receiving the id of that thread. Using that id we search in our threads collection and if there’s a match, we’ll use and add the specific data (title, description, image) to the DOM to display the thread details.

Comments
We have two things related to the comments, newComment() and setUpComments() . In functionality, they are very similar to the newThread() , setUpThreads() .

In the case of setUpComments() we aren’t going to display every comment. Only the ones for the /specific thread are going to be shown. We are checking this with the if(id == comment.thread) part.

No Content
If there is no thread or no comment added we can display an informational message to the viewer about it. The noContent() function plays this role. You could saw it before in the setUpThreads() or setUpComments() .

Deletion
A thread or comment can be deleted by its creator only. To do that, we have to select the id of the element, we want to delete and then check, whether the currentUser is the creator of the content or not.

We also don’t want to show every swiper or rubbish bin icon to the user in every thread or comment which wasn’t created by him/her. Therefore, we have to toggle and hide the option for delete in those cases, when the current user wasn’t the creator of the content. That’s what the deleteOption() is exactly doing.

Enlarge Comment Image
In the beginning, we have introduced this functionality, here is the code for it. First, create variables to reference elements in the HTML. Add a classList to the new comment button to hide it and add the current element’s src to the modalImage.src . The span refers to the closing x, which on click will hide the modal and remove the classList from the new comment button.

Event Listeners
When we tap on a thread, we are getting it’s id and by using that id , we’ll call the previously introduced functions like setUpThreadDetails() , setUpComments() and newComment() .

Dialogs
We use custom dialogs in the application for creating a new thread and new comment. For delete confirmation a built-in f7 function, the dialog.confirm() is enough. In the code, there are some click event listeners too. Those are for closing the opened dialogs.

Conclusion

This is the finishing line! Thank you for reading the article until the end!

We created a relatively simple forum application in this tutorial. If you feel like it feel free to experience or add any advanced features to the app.

Hope you find this useful and gives you a great starting point if you’re new to the framework or Firebase either.

The project’s repo can be found here.

--

--