使用 Firebase (iOS-Swift) 存储用户的 Read/Write 数据

Using Firebase (iOS-Swift) for user's Read/Write data storage

现在 Parse 即将关闭,我想开始使用 Firebase 作为我的主要 BaaS。目前,Firebase 的实时功能很有趣,我认为将来会使用它们,但现在我主要想使用 Firebase 作为存储用户和相关数据的方式。使用 Parse,这非常容易,只需要上传一个对象以及附加到该对象的关联用户。然后我可以过滤与该用户关联的对象。

但是,在 Firebase 中,一切都是事件驱动的,而不是按需驱动的,您不能按安全规则进行过滤。总的来说,我喜欢这种方法,但我在将它应用到我今天需要的东西时遇到了麻烦。我在 networking/databases 方面没有太多背景知识,因此其中一些内容可能非常基础。

这是我想要做的事情:

我的 Firebase 数据结构目前如下所示:

xnterval
   users
      100b920f-d2c5-4578-9f49-ecf38ef71302
      32a8dbf2-009a-44c5-a188-ca2c280ba135
      d53b0b37-d773-4cf5-af94-74635fc76f1f
         name: "Joe Schmo"
         provider: "password"
         username: "jschmo"
         workouts
            -K9wZ4_Rt-xBdVZt93d4
                workout_id: "-K9wZ4_Rt-xBdVZt93d3"
   workouts
      -K9wZ4_Rt-xBdVZt93d3
            interval_period: 180
            intervals: 2
            name: "Workout"
            owner: "d53b0b37-d773-4cf5-af94-74635fc76f1f"
            rest_period: 150
            work_period: 30

在用户内部/"uid" 我有一个锻炼列表,它按 childByAutoId 排序并包含单个锻炼的 ID。

我想要做的是获取所有用户锻炼的列表,然后从锻炼部分检索完整的锻炼列表。

我知道直接指向用户 workouts root/"uid"/workouts 的 PATH,但是我如何检索整个列表并获取每个 "workout_id" 然后随后在中查询该锻炼列表/锻炼部分?

我也已经设置了安全规则,这样其他用户就无法访问其他用户的数据,并且唯一可以 read/write 锻炼的用户是锻炼的所有者是经过身份验证的 UID用户。这个我确实工作正常。

也许我做错了,或者有更简单的方法来构建我的数据来完成我想要的。我阅读了一些关于对数据进行反规范化以优化查询中所需的传输量以及为未来构建的文章,我觉得这种数据结构非常适合。但是,如果您有更多经验,请告诉我。谢谢!

更新

所以我创建了这个方法,它将检索所有用户的锻炼 ID 并将它们存储到数组 userWorkoutIds 中:

private func observeAllUserWorkouts() {
    if userAuthData != nil {
        workoutObserver = userRef?.childByAppendingPath("workouts").observeEventType(FEventType.Value, withBlock: { snapshot in
            let enumerator = snapshot.children
            while let child = enumerator.nextObject() as? FDataSnapshot {
                NSLog("\(child.childSnapshotForPath("workout_id").value)")
                self.userWorkoutIds?.append(child.childSnapshotForPath("workout_id").value as! String)
            }
        })
    }
}

既然我确切地知道了所有用户 workouts/workouts/"IDs" 的路径,我如何才能同时对所有这些路径进行轮询,而不是为所有不同的路径设置单次观察者?或者这是唯一的选择吗?

超级快速的解决方案:将用户的 uid 添加到 workout_id 节点。

然后您可以在锻炼节点上查询等于您要检索其锻炼的用户的 uid。

workouts
   workout_id_0
     interval_period: 180
     internvals: 2
     uid: user_id
   workout_id_1
     interval_period: 180
     internvals: 2
     uid: user_id

第二个选项:

如果您知道用户锻炼的路径

/users/uid_id/workouts

您可以按值观察节点,这会将该节点中的所有子节点读入快照。然后迭代快照以获取特定数据。我个人会将快照中的每个项目加载到字典数组甚至锻炼对象中。