Firebase 3 - Many-to-many relationships…can't quite get it

时光毁灭记忆、已成空白 提交于 2019-12-08 10:28:29

问题


I'm relatively new to Firebase, as well as the new Query API that comes along with it.

Basically, I've got a data store setup where users can add videos from YouTube that they showcase on their profiles. Since users can have many videos and videos can have many users, I've attempted to construct my data store in the appropriate fashion, based on best practices, as shown here:

{
    users {
     c25zdGFyb3NjaWFrQGdtYWlsLmNvbQ==
       videos {
         AFA-rOls8YA: true,
         AlLsp4gnyDQ: true,
         dX_1B0w7Hzc: true,
         ik5qR5bw75E: true,
         njos57IJf-0: true
       },
       videos {
         AFA-rOls8YA {
           attached_members {
             c25zdGFyb3NjaWFrQGdtYWlsLmNvbQ==: true
           }
           title: "Hello...it's me"
         },
         AlLsp4gnyDQ: { ... },
         dX_1B0w7Hzc: { ... },
         ik5qR5bw75E: { ... },
         njos57IJf-0: { ... },
         zn7-fVtT16k
        }
      }
    }
}

What can I do to query these objects in such a way where I can get back a single user that looks like this:

c25zdGFyb3NjaWFrQGdtYWlsLmNvbQ: {
  videos: {
     AFA-rOls8YA: {
       attached_members: { ... }
       title: "Hello...it's me"
     },
     AlLsp4gnyDQ: { ... },
     dX_1B0w7Hzc: { ... },
     ik5qR5bw75E: { ... },
     njos57IJf-0: { ... },
     zn7-fVtT16k: { ... }
  }
}

I have many instances where something like this is going to need to happen. I'm currently using Ionic 2, AngularFire 2, but can use the native Javascript SDK if needed. I see many posts about structuring the data in this way, but I don't see that posts as straight forward as answering how to get it in the most optimized modern way, with Firebase 3.

Any thoughts on how to do this?


回答1:


So the reason they have you desegregate is to be able to bind to endpoints without loading a ton of data. If you had all your data under a single node when you load that node you'd get the entire tree.

We do what you are trying to do often, but it's not a single query call.

I see 2 main options,

One: A function to do a big loop over the results:

public getUser(userKey: string) {
  // assumes using af2
  return this.af.database.object('path/to/users/' + 'userKey').map((user) => {
    for ( let vidKey in user.videos) {
      if (user.videos.hasOwnProp(vidKey)) {
        this.af.database.object('path/to/vids/' + vidKey).map((video) => {
          user.videos[vidKey] = video;
        });
      }
    }
    return user;
  });
};

This would load your user as an object, then load each video and update the object when the data is loaded. Now I'd only use this method if you actually need one big object but I think you just want to display it in a list of users, then details on each vid:

Option 2: Smaller functions

TS:

// before constructor
public user = this.getUser('1234');

//after constructor
public getUser(userKey: string) {
  return this.af.database.object('path/to/users/' + userKey);
}
public getUserVids(userKey: string) {
 return this.af.database.list('path/to/users/' + userKey + '/videos');
}
public getVideo(vidKey: string) {
  return this.af.database.object('path/to/vids/' + vidKey);
}

In the template:

<div class="user" *ngIf="user">
    <h3>Name: {{user.name}}</h3>
    <div class="video" *ngFor="let video of geUserVids(user.$key) | async">
        <p>title: {{video.title}}</p>
        <p>length: {{video.length}}
    </div>
</div>

This way is much smaller and the functions could be used in different places. This uses the observables return from AF2 but is probably what you really want to do, not a giant json object...



来源:https://stackoverflow.com/questions/40551160/firebase-3-many-to-many-relationships-cant-quite-get-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!