列出Firebase数据和关系

时间:2017-09-16 08:55:36

标签: ios firebase firebase-realtime-database

我刚刚开始使用Firebase数据库,我对如何构建数据库感到有些困惑。在以下示例中,我有一个users对象和一个groups对象。每个用户可以是多个组的一部分,每个组可以有多个用户。根据" Structure Your Database"。

,建议的数据库结构如下
{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      "groups": {
         "techpioneers": true,
         "womentechmakers": true
      }
    }
  },
  "groups": {
    "techpioneers": {
      "name": "Historical Tech Pioneers",
      "startDate": "24-04-1820",
      "members": {
        "alovelace": true,
        "ghopper": true,
        "eclarke": true
      }
    }
  }
}

我想说我想在我的应用中显示列表中的所有群组,包括群组名称和开始日期。我该如何进行数据库调用?由于用户对象只包含组的id,我是否必须为每个组单独调用数据库才能找到组的名称和开始日期?如果列表中有许多组,那么这将成为很多调用。我的小组可能还包含很多其他信息,所以这对性能似乎并不好。我可以在一次通话中获取用户的组列表中的所有组吗?

我曾经在用户名下的groups对象中包含名称和开始日期:

"users": {
    "alovelace": {
      "name": "Ada Lovelace",
      "groups": {
         "techpioneers":{ 
            "name": "Historical Tech Pioneers",
            "startDate": "24-04-1820"
          },
         "womentechmakers":{ 
            "name": "Women in Technology",
            "startDate": "13-10-1823"
          }
      }
    }
  }
}

但这个解决方案似乎添加了大量重复数据。此外,如果我想更新名称,我将不得不在多个位置执行此操作。也许我想添加一个赞助商组织对象,它也包含组,然后想要列出它们。然后将有3个地方更新信息。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您将有两种可能性,一种是在每个用户的组节点中存储您需要的数据(复制它)。

另一个,我最推荐的那个,就是在你的第一个观察者中添加observeSingleEvent(of: .value)(可能是observe(.value)observe(.childAdded)或其他什么) 。

假设您拥有一个包含所有群组成员的数组,以及一个名为AppUser的对象,该对象代表您应用中的用户:

var groupMembers = [AppUser]()

例如,要检测何时将新成员添加到组中,您可以使用.childAdded观察者,例如:

func groupWasAddedObserver(completion: @escaping () -> ()) {

        // Add a .childAdded observer to the group's members node (groupId should be defined somewhere) :

        groupsRef.child(groupId).child("members").observe(.childAdded, with: { [weak self] (snapshot) in

                // When you get the snapshot, store its key, which represents the member id :

                let memberId = snapshot.key

                // fetch this member's profile information using its id :

               self?.getUser(memberId, completion: { (groupMember) in

                    // Once you got the profile information of this member, add it to an array of all your members for example :

                    self?.groupMembers.append(groupMember)

                    // Call the completion handler so that you can update the UI or reload a table view somewhere maybe depending on your needs :

                    completion()

               })
        })
}

第二种获取用户数据的方法,知道他或她的身份:

func getUser(_ userId: String, completion: @escaping (AppUser) -> ()) {

   // Add the observerSingleEvent observer :

   usersRef.child(userId).observeSingleEvent(of: .value, with: { (snapshot) in

            // Get the data you need using the snapshot you get : 

            guard let email = snapshot.childSnapshot(forPath: "email").value as? String else { return }
            guard let name = snapshot.childSnapshot(forPath: "name").value as? String else { return }
            guard let picUrl = snapshot.childSnapshot(forPath: "picUrl").value as? String else { return }

            // Call the completion handler to return your user/member :

            completion(AppUser(id: snapshot.key, email: email, name: name, picUrl: picUrl))

        })
 }

如您所见,您使用快照键获取每个用户的memberId,并使用此memberId获取此特定用户数据。