设计基于Firebase的可扩展提要模型 [英] Designing a Firebase based scalable feed model

查看:97
本文介绍了设计基于Firebase的可扩展提要模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:



如何设计以Firebase为后端的社交网络提要(Feed)?



可能的答案:



MVP解决方案是设计供稿根孩子,每个用户一个,并在每个关注者的供稿中追加关注用户的任何新帖子。

 用户
user1
名称:bob
user2
名称:alice
遵循:
user1:true

posts
post1
作者:user1
文字:''

供稿
user2
post1:真实的

这很好用,并且在 Firefeed 项目中进行了演示。但这并不能很好地扩展:如果凯蒂·佩里(Katy Perry)想发布一些东西,她的手机将不得不写上数百万个提要。 = https://stackoverflow.com/questions/27544325/firebase-data-structure-is-the-firefeed-structure-relevant>此SO问题,以将该操作委托给基于服务器的进程。



我的问题是,Firebase是无后端解决方案,这是我使用它的主要原因,因此,我想确保



如果在上述模式中删除了 feeds 子级该怎么办? ?



然后执行此操作:

  baseRef.child('posts ')
.orderBy('作者')
.whereIn(baseRef.child('users / user2 / follows')。keys())

不幸的是, whereIn 在Firebase API中不存在,也没有子查询:(



不需要服务器就可以使用其他模型结构吗?



谢谢

解决方案

Firebase家伙在他们的博客上回答: https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html



该帖子的主题是数据扇动(在一个原子写入操作中将项目分布在多个节点上)。



该技术极大地解决了原始问题的供稿模型



该帖子实际上包含实现该示例的示例代码:




  • 创建扇出对象的功能(实际上是一个简单的对象,其键为要写入的API端点)

      function fanoutPost({uid,followersSnaphot,post}){
    //将跟随者的哈希值转换为每个id的数组,如字符串
    var followers = Object.keys(followersSnaphot。 val());
    var fanoutObj = {};
    //写入每个关注者的时间轴
    followers.forEach((key)=> fanoutObj [’/ timeline /’+ key] = post);
    return fanoutObj;
    }


  • 以及使用此功能的逻辑:

      var followersRef = new Firebase('https://< YOUR-FIREBASE-APP&。; firebaseio.com/followers'); 
    var followers = {};
    followersRef.on('value',(snap)=> followers = snap.val());
    var btnAddPost = document.getElementById(’btnAddPost’);
    var txtPostTitle = document.getElementById(’txtPostTitle');
    btnAddPost.addEventListener(()=> {
    //创建帖子
    var post = {title:txtPostTitle.value};
    //创建扇出对象
    var fanoutObj = fanoutPost({
    uid:followersRef.getAuth()。uid,
    followers:followers,
    post:post
    });
    //发送Firebase数据库的对象,用于扇出
    rootRef.update(fanoutObj);
    });







注意:这比每次在一个关注者提要中的循环编写都具有更大的可扩展性。但是,对于数百万的追随者来说,这可能是不够的。在这种情况下,信任多次写入的服务器操作会更安全。我认为客户端最多可用于数百个关注者,这是社交媒体上关注者的平均数量。 (不过,这需要通过测试进行验证)


Question :

How to design a social network "feed" with Firebase as backend, that scales ?

Possible answers :

"MVP" solution is to design a feeds root child, one for each user, and append any new post from the followed user in every follower's feeds.

users
  user1
    name: bob
  user2
    name: alice
    follows: 
      user1: true

posts
  post1
     author: user1
     text: 'Hi there'

feeds
  user2
    post1: true

This works well, and is demoed in the Firefeed project. But it does not scale well : if Katy Perry wants to post something, her mobile phone will have to write to millions of feed.

Hence the solution reported in this SO question to delegate this operation to a server based process.

My problem is, Firebase is a "no-backend" solution, and this is the main reason why I use it, so I'd like to make sure there is absolutely no chance of implementing this feature without a server.

What if the feeds child is removed in the above schema ?

Then do this :

baseRef.child('posts')
       .orderBy('author')
       .whereIn(baseRef.child('users/user2/follows').keys())

Unfortunately, whereIn does not exists in Firebase API, nor subqueries :(

Any other model structure possible without the need of a server ?

Thanks

解决方案

Firebase guys kinda replied on their blog : https://www.firebase.com/blog/2015-10-07-how-to-keep-your-data-consistent.html

The post is about "Data fanning" (spreading items across many nodes in one atomic write operation).

The technique greatly addresses the feed model of the original question

The post actually contains example code for implementing it :

  • Function for creating the fannout object (actually a simple object with keys being API endpoints to be written)

    function fanoutPost({ uid, followersSnaphot, post }) {
            // Turn the hash of followers to an array of each id as the string
            var followers = Object.keys(followersSnaphot.val());
            var fanoutObj = {};
            // write to each follower's timeline
            followers.forEach((key) => fanoutObj['/timeline/' + key] = post);
            return fanoutObj;  
    }
    

  • And the logic using this function :

    var followersRef = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/followers');
    var followers = {};
    followersRef.on('value', (snap) => followers = snap.val());
    var btnAddPost = document.getElementById('btnAddPost');
    var txtPostTitle = document.getElementById('txtPostTitle');
    btnAddPost.addEventListener(() => {
          // make post
          var post = { title: txtPostTitle.value };
          // make fanout-object
          var fanoutObj = fanoutPost({ 
              uid: followersRef.getAuth().uid, 
              followers: followers, 
              post: post 
          });
          // Send the object to the Firebase db for fan-out
          rootRef.update(fanoutObj);
    });
    


Note: this is way more scalable than a loop writing each time in one follower feed. However, it could nevertheless be insufficient for millions of followers. In that case, it would be safer to trust a server operation making several writes. I think client-side can be used for up to a few hundreds followers, which is the average number of followers on social media. (This needs to be verified by testing though)

这篇关于设计基于Firebase的可扩展提要模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆