Best way to structure and share data with other users


#1

I’m trying to limit which users have access to the information in the “messages” node. I currently have that a user with uid “NlzHs5O2zUZ68qCFDFgHotCWuqs1” publishes a message and would like that that same user (“NlzHs5O2zUZ68qCFDFgHotCWuqs1”) as well as a select other node of users called “receivers” can view that message. Currently there is only one user under “receiver” node but in the future there would be many more. However, I’m struggling to limit who can read the message. Right now, applying “.read” rules does not work to restrict viewing. Everyone, including other users in the “messengers” node can see the message. What is the best way to have that only the messenger who posts the message as well as other users in “receivers” can view it while restricting all other users in “messengers”? Thanks!

This is my firebase data below:

- messages
   -LE7HkwddRFPvH_JyEyv
     subtitle: "New"
     title: "Hi All"
     userId: "NlzHs5O2zUZ68qCFDFgHotCWuqs1"


-receivers
  -umoI4fowVXY0dd9E3H8l5JS2Sdp1
     email: "44@2.com"
     uid: "umoI4fowVXY0dd9E3H8l5JS2Sdp1"


-messengers
  -6wxmnugRoVOOWqljloSdgYjc0gb2
     email: "99@4.com"
     uid: "6wxmnugRoVOOWqljloSdgYjc0gb2"
  -NlzHs5O2zUZ68qCFDFgHotCWuqs1
     email: "88@3.com"
     uid: "NlzHs5O2zUZ68qCFDFgHotCWuqs1"

Rules:

"messages": {

      "$itemId" : {
        ".read" : "auth != null && auth.uid === data.child('userId').val()",
        ".write" : "auth.uid === data.child('userId').val() ||
                                data.child('userId').val() === null"
      },
      ".read" : root.child('receivers').child(auth.uid).exists()
    },

Reading through similar issues, I thought about restructuring my data to look something like this:

-messages
   -NlzHs5O2zUZ68qCFDFgHotCWuqs1
      -LEGP9LSTD1H6sjUPoeE
        subtitle: "Newer"
        title: "Hey Y'all"

But then I encountered another roadblock where I can’t get other users to see the message info because the info is under the uid of the user who posted the message. Below is a snippet of the other code if I restructured:

itemListRef = firebase.database().ref(`messages`);

constructor(public navCtrl: NavController, public navParams: NavParams,
    private afAuth: AngularFireAuth, public afdb: AngularFireDatabase) {
    this.afAuth.authState.subscribe((auth) => {
        this.authState = auth
    });

}

addMessage(item: Message) {
    this.itemListRef.child(this.afAuth.auth.currentUser.uid).push({
        title: this.item.title,
        subtitle: this.item.subtitle,
       })
    this.navCtrl.pop();
}

#2

Hi

three things I would say:

  • go to Firestore if still possible, Firebase Realtime db is old fashioned
  • it should not be an issue to duplicate data in order to create access for other users (write under a private node and to a public node)
  • make data structures as flat as possible

Tom


#3

Thanks for the tip, Tom! Is it easy to switch over, you’d say?


#4

Well, not sure how much code and data u have

But why wont give it a glance and try it out

The api is different including the rules

But allows for better querying


#5

I’ve got a bit of code already, several pages and services made already. Will check it out though.


#6

What I needed to do was to add
this.afdb.list(products, ref => ref.orderByChild(‘userId’).equalTo(this.afAuth.auth.currentUser.uid)) on the seller.ts page, and leave firebase rules alone.