0

I am creating simple crud web app, which allows designated user to create, and both login user and non-user can read the saved posts. I wonder how to structure firebase rule to achieve this?

I checked recommendation from this post: Firebase: How to structure public/private user datae, and come to my own solution as below.

I created two nodes: private (users) and public (posts), and at my redux action. I tried to write the data twice at both private and public, but get permission denied from the firebase.

My question is how to bypass this error, or if there is better approach to tackle this.

Thanks

My firebase rule:

{
    "rules": {
    "users": {
        "$user_id": {
            ".read": "$user_id === 'Set_User_Id'",
            ".write": "$user_id === 'Set_User_Id'",
                "posts": {
                "$post_id": {
                    ".validate": "newData.hasChildren(['title', 'postType', 'image', 'createdAt', 'note', 'link'])",
                        "title": {
                        ".validate": "newData.isString() && newData.val().length > 0"
                    },
                    "postType": {
                        ".validate": "newData.isString()"
                    },
                    "createdAt": {
                        ".validate": "newData.isNumber()"
                    },
                    "image": {
                        ".validate": "newData.isString()"
                    },
                    "link": {
                        ".validate": "newData.isString()"
                    },
                    "note": {
                        ".validate": "newData.isString()"
                    },
                    "$other": {
                        ".validate": false
                    }
                }
            }, 
            "$other": { 
                ".validate": false 
            }
        }
    },
        "posts": {
    ".read": true,
    "$user_id": {
        ".write": "$user_id === 'Set_User_Id'",
    }
  }
}

}

Redux Action for add data twice. one at private node (users), and another at public node (posts).

export const startAddPost = (postData = {}) => {
return (dispatch, getState) => {
    const uid = getState().auth.uid;
    const {
        title = '',
        postType = '',
        image = '',
        createdAt = 0,
        note = '',
        link = ''
    } = postData;
    const post = { title, postType, image, createdAt, note, link }

    return (
        database.ref(`users/${uid}/posts`).push(post).then((ref) => {
            dispatch(addPost({
                id: ref.key,
                ...post
            }))
        }) &&
        database.ref('posts').push(post).then((ref) => {
            dispatch(addPost({
                id: ref.key,
                ...post
            }))
        })
    )
}

};

Tony
  • 25
  • 6
  • 1
    What's the problem with this code? – Frank van Puffelen Jun 29 '19 at 05:28
  • I found a potential solution from https://stackoverflow.com/questions/38648669/firebase-how-to-structure-public-private-user-data, but could not write the data twice (in private and public) without error. This approach seems to be pretty redundant, since you need to inject same data twice to the database. I wonder whether this is any other solution to tackle this. Thanks. – Tony Jun 29 '19 at 06:09
  • Storing redundant data is quite common in NoSQL databases. If you're new to that, I recommend reading [NoSQL data modeling](https://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/) and watching [Firebase for SQL developers](https://www.youtube.com/playlist?list=PLl-K7zZEsYLlP-k-RKFa7RyNPa9_wCH2s). – Frank van Puffelen Jun 29 '19 at 06:17
  • This looks weird: `".write": "$user_id === 'Set_User_Id'"`. Are you looking to do `".write": "$user_id === auth.uid"`, as shown [here](https://firebase.google.com/docs/database/security/user-security)? – Frank van Puffelen Jun 29 '19 at 06:20
  • Thanks. I have created a set of users that can write the database, "Set_User_Id", is just placeholder for the variable. – Tony Jun 29 '19 at 06:40
  • It still makes no sense, even with a fixed UID (btw: there's [no risk in sharing UIDs](https://stackoverflow.com/questions/37221760/firebase-is-auth-uid-a-shared-secret)). The rule essentially says that everyone can write that UIDs data, which is not likely what you want. – Frank van Puffelen Jun 29 '19 at 07:30
  • Ah Ha!! that makes much more sense now. Thank you so much~ – Tony Jun 29 '19 at 08:04

0 Answers0