Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Firestore comment tree architecture

I'm trying to implement a Reddit/HackerNews style tree of comments as part of a project, and am trying out Firestore as a database solution. However, I'm unsure as to the correct design reading through the docs. In a SQL database I would use numeric keys like:

0
1.0
1.1
1.1.1
0.0

to represent my tree. However, numeric keys like that seem to be a Firebase antipattern. The other route is using an actual tree in the json where a post is represented like:

{
  uid: 'A0000',
  content: 'foo',
  children: [
    {uid:..., content:..., children: []}]
}

but supposedly deep trees are bad in Firestore. As I understand it the reason deep trees are bad is that you have to fetch the whole thing, but in my case I'm not sure if that's a problem. A client fetching a post would fetch the root content node and the first 20 or so child trees. That could be a pretty big fetch, but not insanely so.

Does anyone know of a good standard way to implement this kind of structure?

Extra: Here is the more verbose expression of what the structure should look like once the client processes it.

{
  uid: 0,
  title: 'Check out this cat!',
  body: 'It\'s pretty cute! This **text** is [markdown](link), so it can have ' +
    'links and *stuff*. Yay!',
  poster: {
    uid: 0,
    name: 'VivaLaPanda',
    aviUrl: 'badlink',
  },
  posted: '2018-03-28',
  children: [{
      uid: 0,
      body: 'This is a comment, it\'s angry!',
      poster: {
        uid: 0,
        name: 'VivaLaPanda',
        aviUrl: 'badlink',
      },
      posted: '2018-03-20',
      children: [{
        uid: 0,
        body: 'This is a comment, it\'s neutral!',
        poster: {
          uid: 0,
          name: 'Steve',
          aviUrl: 'badlink',
        },
        posted: '2018-03-20',
        children: [{
          uid: 0,
          body: 'This is a comment, it\'s neutral!',
          poster: {
            uid: 0,
            name: 'Craig',
            aviUrl: 'badlink',
          },
          posted: '2018-04-10',
          children: []
        }, ]
      }, ]
    },
    {
      uid: 0,
      body: 'This is a comment, it\'s happy!',
      poster: {
        uid: 0,
        name: 'Craig',
        aviUrl: 'badlink',
      },
      posted: '2018-03-28',
      children: []
    },
  ]
};

Edit:

While I've marked this as answered because there is an answer, I'm still really interested in seeing something more elegant/efficient.

Edit2:

For posterity: I ended up deciding that any Firebase solution was hopelessly convoluted and just used DGraph for the data, with Firebase sitting in front for Auth.

like image 441
VivaLaPanda Avatar asked Apr 15 '18 20:04

VivaLaPanda


1 Answers

Your children approach could be really messy if there are a lot of people commenting on eachother. A nicer approach would be the following structure for every comment:

// single comment

postUid // <- random generated by firebase
{
    postedBy: userUid
    postedTime: timestamp
    postIsChildOfUid: postUid // <- reference to an other post (optional if the comment didn't respond to another comment(top-level comment))
}

This doesn't even require nesting at all :). You can generate easily now a comment tree with this approach, but this has to be client side. But that should be easy!

like image 197
J. Doe Avatar answered Sep 27 '22 21:09

J. Doe