Javascript Firebase云功能避免客户端工作总是值得的吗?

Javascript Firebase云功能避免客户端工作总是值得的吗?,javascript,firebase,firebase-realtime-database,google-cloud-functions,nosql,Javascript,Firebase,Firebase Realtime Database,Google Cloud Functions,Nosql,我最近正在使用Firebase云功能将大量工作从客户端委托给服务器,从而降低了用户的数据成本。但最近我想知道它是否值得,或者也许一个更好的数据库结构可以修复它 我有一个社交应用程序,用户可以锻炼并发布他们的结果,你可以跟踪用户和各种“典型”的社交媒体内容。好吧,当我想要实现分页检索我应该在每个用户的提要上向他们显示的最后X个训练时,我的问题就出现了 我的问题是:在Firebase云函数的公共事件触发器上,从数据库上的1-1000(最坏情况)字段进行更新的成本有多高。在客户端,这已经足够昂贵了,可

我最近正在使用Firebase云功能将大量工作从客户端委托给服务器,从而降低了用户的数据成本。但最近我想知道它是否值得,或者也许一个更好的数据库结构可以修复它

我有一个社交应用程序,用户可以锻炼并发布他们的结果,你可以跟踪用户和各种“典型”的社交媒体内容。好吧,当我想要实现分页检索我应该在每个用户的提要上向他们显示的最后X个训练时,我的问题就出现了

我的问题是:在Firebase云函数的公共事件触发器上,从数据库上的1-1000(最坏情况)字段进行更新的成本有多高。在客户端,这已经足够昂贵了,可以避免它,并寻找更好的方式来讨论性能,即使在客户端,这会更昂贵吗

我将通过我的例子来解释:

数据库结构

"privateUserData" : {
    "user1" : {
      "messagingTokens": {
        "someToken": true,
        "someToken2": true,
      },
      "accountCreationDate" : 1495819217216,        
      "email" : "abcd@gmail.com",
      "followedBy" : {
        "user2": true,
        "user3": true,
      },
      "following" : {
        "user2": true,
        "user3": true,
      },        
      "lastLogin" : 1498654134543,
      "photoUrl" : "photo.png",       
      "username" : "Francisco Durdin Garcia"
    },
  },
  "publicUserData": {
    "user1": {
      "username": "someUserName",
      "followersCount": 5,
      "followingCount": 1,
      "photoUrl" : "someUrl"
    }
    ...
  },
  "workouts" : {
    "workout1" : {
      "likes": {
        "user1": true,
        "user2": true,
        ...
      },
      "followers": {
        "user1": true,
        "user2": true,
        ...
      },
      "comments": {
        "comment1": {
          "owner": "user1",
          "content": "somecomment",
          "time": 1493153530311,
          "replies": {
            "reply1": {
              "owner": "user1",
              "content": "somecomment",
              "time": 1493153530311,
            }
          }
        }
      }
      "authorUid" : "user1",
      "description" : "desc",
      "points" : 63,
      "time" : "00:03",
      "createdAt" : 1493153530311,
      "title" : "someTitle",
      "workoutJson" : "workoutJsonDataHere"
    }
  }
为了能够进行该查询,我应该为我关注的每个用户进行单独的查询:

问题是我可以执行“全局”查询,并将其限制为仅X个dataSnapshots。我可以为每个查询筛选一些训练:

mDatabase.child("workouts").orderByChild("authorId).equalTo("userIFollow").limitToLast(10)
此查询将返回一个仅对一个
userIFollow
应用的筛选器。不可能对所有用户都应用此筛选器,因此我有三个选项:

一,。创建一个表,该表存储了
usersId
workoutsId
之间的关系,它们通过
时间戳
值可见。但我应该 通过Firebase云函数跟踪此值,以及 很明显,我可能会跟随一个用户进行数千次训练 云函数需要将它们全部复制到右侧 参考资料

这是我想走的路,但我不知道是不是 谈论客户方成本的正确方式

二,。我可以在
publicUserData
上添加
lastActivityTimeStamp
,然后通过它进行过滤,只检索最后一个有活动的用户的一些训练,并通过分页扩展此查询

三,。最后,我总是可以从这个用户那里检索所有的训练,并在客户端进行筛选,这将是昂贵的,因为稍后缓存将使一切变得更容易


这是我找到的解决问题的方法,我的问题仍然是使用常见触发器复制大量数据的Firebase云函数有多昂贵和有用。

从您的问题措辞来看,您似乎熟悉Firebase的数据库云功能,而且“训练”似乎是您的有效负载(您不想重复下载的最大数据块)

我将根据工作原理推荐以下方法

先决条件 在您的
/privateUserData/{user}
数据中,您似乎有以下用户ID列表(位于
/privateUserData/{user}/后面的
)。为了简化查询,我建议实现由该用户编写的训练ID列表(在类似于
/publicUserData/{user}/authorOf
的内容下)

实施 我建议在say
https://FUNCTION_URL/followedWorkouts
。调用时,您将为给定用户生成一个训练ID列表,方法是检查他们跟随谁,然后获取每个跟随用户编写的训练列表,并将其作为一个数组返回。要识别用户,您可以使用GET参数(如
?user=
)或通过某种形式的身份验证来传递他们的ID。你怎么做取决于你自己

函数应以以下(或类似)格式返回数据(在本例中,我使用的是JSON):

  • id
    是训练id
  • lastMod
    (last modified的缩写)是上次更新训练数据的时间(从
    {workoutId}/lastModificationDate
    )。请参阅下面的“缓存”部分
过滤 我还将在云函数上实现以下“过滤器”:

  • 自(
    ?自=
    ):
    将返回自该时间戳以来修改过的训练ID。(假设您在某个时间下载了一些信息,
    T
    ,然后将
    since=T
    设置为仅接收在该时间之后更改的训练
  • Max(
    ?Max=X
    ):
    将返回X个最近的条目
  • 从(
    ?startAt=X
    )开始:
    将返回从索引X开始的最新条目(我将它设为基于1的索引)
因此,如果您想获取最近的10个条目,可以调用
https://FUNCTION_URL/followedWorkouts?max=10
这将为您提供第一至第十次最新更新训练的ID。对于下一个“页面”条目,您可以调用
https://FUNCTION_URL/followedWorkouts?startAt=10&max=10
这将为您提供1第1-20次最新更新的训练ID

缓存 由于每个训练都是一个有效载荷,因此多次下载没有意义。我建议缓存这些数据以防止出现这种情况。在我上面建议的响应中,字段
lastMod
(上次修改)允许您检查本地缓存的版本是否需要更新。如何进行此操作,再次取决于您

延伸 如果需要更多这些分页提要,可以更一般地命名函数,如
https://FUNCTION_URL/feeds
并将馈送类型作为参数传递
https://FUNCTION_URL/feeds?type=workouts
。您可以将其用于
关注者
关注者
评论
,等等


如果您需要更多信息,请随时联系。

从您回答问题的方式来看,您似乎熟悉Firebase的数据库云功能,而且“训练”似乎是您的有效负载(您需要的最大数据块)
[{"id": "workoutId1", "lastMod": "1493153530311"}, {"id": "workoutId2", "lastMod": "1493153530521"}, ...]