Firebase firestore in the forum application #13: Comment collection and Render comment data to the template

in #utopian-io5 years ago

Repository

https://github.com/firebase

What Will I Learn?

  • Comment collection
  • Render comment data to the template

Requirements

  • Basic Javascript
  • Install Firebase

Resources

Difficulty

Basic

Tutorial Content

In this tutorial, we will continue the next tutorial. This is an advanced tutorial series from the previous tutorial, for those of you who are just following this tutorial, I suggest you follow the curriculum in this tutorial so that you are not confused. This tutorial continues from the previous tutorial about the comment feature on the forum application. In the previous tutorial, we have succeeded in creating a collection of new replies in the forums document. For that, we just continue the following tutorial.

Comment collection

In previous tutorials we have successfully added comments to our forum collection, you can see it in more detail in this tutorial. In the tutorial we have added a subcollection to the firestore database that we are using. what is subcollection ?

  • Subcollection in the forums

Subcollections are collections in collection documents. So in the example of this tutorial, we have a collection in the forums document. The subcollection is replies. Sub-collections are the same as collections in general in the form of objects, But to access them, we must first access documents in the main collection. more and more subcollections within the subcollection are increasingly complicated to access and maintain. it is recommended to use only a maximum of 3 levels of collection. For more details, we can see in the picture below:

Screenshot_13.png

We can see in the picture above, that's the structure of the database firestore in this tutorial. You can see for URLs or directories that are formed as follows: /forums/0x0LDyVYx5ymnc7lmUls/replies/t1Q0tiFZCSEylsjFVC4l.

Documents from each collection are generated automatically by firebase. So to access the collection in it we need to know the document id.

Load comment

Well, we already have knowledge about subcollections and the previous tutorial we have inserted into the subcollection, now in this section, we will learn how to load data from the subcollection in the template. As we discussed before to access subcollections we must have the ID documents. So far we have successfully loaded the data forums. Well right after the forum data has been loaded we will also load comments on the forum. for more details you can see in the example below:

index.js

app.get('/forum/:slug', function(req, res) {
var forum = null;
    db.collection('forums').where('slug', '==', req.params.slug).get()
    .then(snapshot => {
        snapshot.forEach(doc => {
            forum = doc.data()
            forum.id = doc.id
        })

        // Load replies
        var replies=[]
        db.collection('forums').doc(forum.id).collection('replies').get()
            .then(snapshot => {
            // you can get comment data here
            })
            //end load
        res.render('forum-detail', {forum:forum})
    }).catch(err => {
        console.log(err)
    })
});

We will load the data from the backend cloud function at index.js. the data will be loaded when we will access the forum URL details.

Same as data forums, we will create an array to store the load results from the comment data. We can define it like the following var replies = [].

As I discussed in the previous section, to access the subcollection we need the document id from the main collection, here we can access the forum ID through forum.id.

After we get the ID document we can access the subcollections in the document like this db.collection('forums').doc(forum.id).collection('replies').get(). The subcollection that we will access is replies. We can use the get () function to get the data.

  • Render comment data to template

Now we can access the replies subcollection, this means we can sort the comment data in the following way:

index.js

// Load replies
        var replies=[]
        db.collection('forums').doc(forum.id).collection('replies').get()
            .then(snapshot => {
                snapshot.forEach(doc => {
                console.log(doc.data())
                    replies.push(doc.data())
                })
            })

We can get the response in the snapshot. Well, the data in the snapshot will be forEach ()and pushed into the array that we defined earlier, namely replies. We use forEach because each forum allows having several comments.

After issued it we will push the data one by one into the array replies variable that we have defined above. I will do console.log(doc.data()) to see the data that we are going to render. We can see an example in the picture below:

Screenshot_14.png

We can see in the picture above we managed to get the replies sub-collection data. Then we will try to render the data in the template:

index.js

var replies=[]
        db.collection('forums').doc(forum.id).collection('replies').get()
            .then(snapshot => {
                snapshot.forEach(doc => {
                    replies.push(doc.data())
                })
            })
        res.render('forum-detail', {forum:forum, comments:replies})

Before rendering comments on the template we are using, we need to collect the data into an array that we have defined above, namely replies = []. We can collect comment data in the following way replies.push(doc.data()). The data we will push is on doc.data ().

After we collect the data in an array, we can pass it to render it to the forum-detail template. the data that we have passed in the form of object keys and values. the key is comments and the value is replies.

  • Rendering comments on templates

We have passed the value to the template, now we can render it in the forum-detail template. The data that we passed is comments. The comment is the key that we have shifted in the backend. For more details we can see the template as follows:

forum-detail.hbs

<div class="jumbotron">
    <h1 class="display-4">Hi, This the single forum. you can see any detail!</h1>
    <hr class="my-4">
    <p>It uses utility classes for typography and spacing to space content out within the larger container.</p>
    <p class="lead">
    <button class="btn btn-danger" type="button" name="button" onclick="login('gmail')">Login Gmail</button>
    <button class="btn btn-primary" type="button" name="button" onclick="login('fb')">Login FB</button>
    <button class="btn btn-info" type="button" name="button" onclick="login('twitter')">Login Twitter</button>
    <button class="btn btn-success" type="button" name="button" onclick="logout()">Log out</button>
    </p>
    <hr>
    <h2>Forum {{forum.title}}</h2>
    <p>{{forum.desc}} <span><i>by: <b>{{forum.user.username}}</b></i></span></p>
    <input type="hidden" name="owner_uid" id="owner_id" value="{{forum.user.user_id}}">
    <a href="#" class="btn btn-info is-hidden" id="btn-edit" onclick="showEditForm()">Edit</a>
</div>
<div class="is-hidden" id="editForm">
    <div class="row">
        <div class="container">
            <form>
                <div class="form-group">
                    <label for="title">Title</label>
                    <input type="text" class="form-control" id="title" value="{{forum.title}}" placeholder="Your tittle">
                </div>
                <div class="form-group">
                    <label for="desc">Desciptions</label>
                    <textarea class="form-control" id="desc" rows="3">{{forum.desc}}</textarea>
                </div>
                <button class="btn btn-info" type="button" name="button" id="update-btn" onclick="updateForum('{{forum.id}}')">Update</button>
            </form>
        </div>
    </div>
</div>
<br>
{{#each comments}}
    <p>{{desc}}</p>
{{/each}}
<div class="row">
    <div class="container">
        <div class="form-group">
            <textarea class="form-control col-md-6" id="comment" rows="3" placeholder="Your comment" style="margin-bottom:5px;"></textarea>
            <button type="button" class="btn btn-success" onclick="addComment('{{forum.id}}')">Add comment</button>
        </div>
    </div>
</div>

After we pass the data we can do a foreach to render data one by one. The data we are about to search for is comments. We can use each {{#each}}. We can render {{desc}} in the tag <p>. After we follow the tutorial we can test whether our function is working properly:

Screenshot_15.png

ezgif.com-video-to-gif (3).gif

we can see in the picture above we have successfully rendered comments on the template in the forum-detail. This means we have successfully used the comment system that we created on the forum application, thank you for following this tutorial. hopefully, it will be useful for you

Curriculum

  • Forum app

Firebase app#1, Firebase app#2, Firebase app#3, Firebase app#4, Firebase app#5, Firebase app#6, Firebase app#7, Firebase app#8, Firebase app#9, Firebase app#10,

Proof of work done

https://github.com/milleaduski/firebase-forum

Sort:  

Thank you for your contribution @duski.harahap.
After reviewing your contribution, we suggest you following points:

  • Thanks for following some of our instructions in your previous tutorial. Your contribution has been much better.

  • In the requirements it was important to have the link of a tutorial like install the firebase.

  • Be careful in structuring your text from the tutorial. The text needs to be well structured to have a professional presentation.

Thank you for your work in developing this tutorial.
Looking forward to your upcoming tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Chat with us on Discord.

[utopian-moderator]

Thank you for your review, @portugalcoin! Keep up the good work!

Hi @duski.harahap!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @duski.harahap!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!