0

Quite new to Firebase and I'm facing some issue on the logic on querying/filtering the needed requests.

I have my users stored in the /users and they have a list of projects such as :

users : {
  userA : {
    projects: {
      projectId1: true,
      projectId2: true
    },
    ...
  }
...
}

And obviously I have the projects as such:

projects: {
  projectId1: {
    name: "bla"
  }
  ...
}

I want for a user to query all the projects that are in his projects list based on their Ids. Right now I only succeed to query every single projects of the database and their filter on the client side but obviously this has some serious security implication and loading time as well as I don't want anyone to query all the projects and get them. I can add security rules but then I have access to nothing as I can't query /projects/ anymore but need to be specific.

I'm using https://github.com/CSFrequency/react-firebase-hooks/tree/master/database

and getting the data as such:

  const [projects, loading, error] = useListVals(firebase.db.ref("projects"), {
    keyField: "uid",
  });

And so would like to be able to add an array of projected in this request like where({ id is included in [projectsId]})

Ivo
  • 2,308
  • 1
  • 13
  • 28
  • Hi @FrankvanPuffelen Thanks for your answer which was useful. However in full honesty, we are moving away from Firebase as we don't manage to have sufficient control on our database and to implement the proper rules and connections in our data. I guess it's a lack of training/knowlegde on our side but I have to admit using firebase was not the smoothest experience for us :( – Ivo Sep 14 '20 at 08:06
  • Sorry to hear that, and thanks for letting me know Ivo. If I may ask: what solution are you moving forward with? – Frank van Puffelen Sep 14 '20 at 14:56
  • 1
    More classical MERN stack (well actually using meteor so not fully MERN but meteor/react/mongo) – Ivo Sep 21 '20 at 10:02

1 Answers1

1

You'll need to load each individual project for the user separately, pretty much like a client-side join operation. This is not nearly as slow as you may think, as Firebase pipelines the operations over a single connection.

I don't see anything built into the library you use for such client-side joins, but in regular JavaScript it's something like this:

let userRef = firebase.database().ref('users').child(firebase.auth().currentUser.uid);
userRef.once('value').then((projectKeys) => {
  let promises = [];
  projectSnapshot.forEach((projectKey) => {
    let key = projectKey.key;
    let projectRef = firebase.database().ref('projects').child(key);
    promises.push(projectRef.once('value');
  });
  Promise.all(promises).then((snapshots) => {
    console.log(snapshots.map(snapshot => snapshot.val()));
  });
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807