How to share data between users in Firebase?

2020-05-30 03:35发布

问题:

In a database like this:

{
  "users": {
    "simplelogin:213": {    
      "provider": "password",
      "name": "bobtony",
      "friends": {
        "Andrew Lee": true,
        "James Tamplin": true
      }   
    },
    "twitter:123": {
      "provider": "twitter",
      "name": "Andrew Lee",
      "friends": {}
    },  
    "facebook:456": {
      "provider": "facebook",
      "name": "James Tamplin",
      "friends": {}
    }   
  },  
  "messages": {  
    "simplelogin:213": {    
       "-JkpwAnieKjQVsdtPD4m" : {
          "content" : "Hello World"
      }
    }  
  }  
}

Considering that bobtony add Andrew Lee as his friend, how Andrew Lee can read bobtony messages? A similar question asked here, but without good solution. I know I can have a rule to allow reading the message, but the "friend" users just does not to know the path to read them.

Update: After spend some time thinking, i got:

{
  "users": {
    "user1": {  
      "name": "bobtony",
      "partners": {
        "user2": {
            "accepted": true
        }
      },
      "customers":{
        "customer1": true,
        "customer2": true
        // hundreds of clients
      },
      "orders":{
        "order1": true,
        "order2": true
        // hundreds of orders
      }     
    }
  },  
  "customers": {  
    "customer1": {  
       "name" : "james"
      }
    }
}

So, would be ok to have something like this? This way I can traverse my own customers and my partners customers.

回答1:

If you set up your data like so:

{
  "users": {
    "simplelogin:213": {    
      "provider": "password",
      "name": "bobtony",
      "friends": {
        "twitter:123": "Andrew Lee",
        "facebook:456": "James Tamplin"
      },
      "messages": {
        "sent" : {
          "-JkpwAnieKjQVsdtPD4m" : {
            "content" : "Hello World",
            "uid" : "twitter:123"
          }
        }
      }
    },
    "twitter:123": {
      "provider": "twitter",
      "name": "Andrew Lee",
      "friends": {
        "simplelogin:213": "bobtony"
      },
      "messages": {
        "received" : {
          "-JkpwAnieKjQVsdtPD4m" : {
            "content" : "Hello World",
            "uid" : "simplelogin:213"
          }
        }
      }
    },  
    "facebook:456": {
      "provider": "facebook",
      "name": "James Tamplin",
      "friends": {
        "simplelogin:213": "bobtony"
      }
    }   
  }
}

You can set the rules so that one user can write to the /messages/received of another user if the sending user's uid is in the '/friends' of the receiving user.

{
  "rules": {
    "users" : {
      "$user_id" : {
        ".read": "auth.uid === $user_id",
        ".write": "auth.uid === $user_id",
        "messages" : {
          "received" : {
            ".write" : "root.child('users').child($user_id).child('friends').hasChild(auth.uid)"
          }
        }
      }
    }
  }
}

You'd need to use Firebase.transaction() to make sure the write to sent only succeeds if the write to received succeeds.



回答2:

This video is helpful: https://www.youtube.com/watch?v=3hj_r_N0qMs The general idea is the same, instead of isTeacher == true, just add them to the roles of another user (for example userX { usersWithViewAccess : userY, userZ ... } )

service cloud.firestore { 
  match /databases/{database}/documents { 
    match /class/ {classId}/grades/{studentId} {
        allow read: if request.auth.uid == studentld; 
        allow write: if get(/databases/$(database)/documents/ 
        administrators/$( request. auth.uid)).data.isTeacher == true; 
        }
    }
}

With this as the rules

administrators: { 
    userid123: { 
        isTeacher : true 
    }
    userid009: { 
        isAdminAssistant : true 
    }
}