2017-09-16 20 views
0

我刚开始使用Firebase数据库,我对如何构建数据库感到困惑。在下面的例子中,我有一个用户对象和一个组对象。每个用户可以是多个组的一部分,每个组可以有多个用户。根据“Structure Your Database”,建议的数据库结构如下。列出Firebase数据和关系

{ 
    "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,那么我是否需要为每个组分别调用一次数据库才能找出组的名称和开始日期?如果列表中有很多组,那么这会变成很多电话。我的团队也可能包含很多其他信息,因此这对于性能来说似乎不太合适。我可以在一次通话中获得用户的群组列表中的所有群组吗?


一个虽然我有是包括名称和起始日期的组,用户可以根据对象:

"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个地方更新信息。我将如何解决这个问题?

回答

0

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

另一方面,我会推荐最多的方法是在第一位观察者(可能是observe(.value),observe(.childAdded)或其他)中添加observeSingleEvent(of: .value)

说你有你的所有组成员的数组,并命名为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() 

       }) 
     }) 
} 

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

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来获取此特定用户数据。