Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
131 views
in Technique[技术] by (71.8m points)

javascript - Firebase can't create new doc

I have a firebase project that, since my last build, will not create new docs. It will save and amend docs, but not create new ones.

The function for creating new docs should create a new doc with a key based on a newly created uid like this:

const sendInformationHandler = () => {
        const customerEmailCurrent = customerEmail.current.value
        const customerPassword = "password"
        if (checkUserEmailExists(customerEmailCurrent)) {
                createUser(
                    {
                        email: customerEmailCurrent,
                        password: customerPassword
                    }
                ).then(function(user) {
                    firebase
                    .firestore()
                    .collection('sessions')
                    .doc(user.data.uid).set(
                        {...context.state}
                    ).then(() => {
                        console.log("DATA SAVED SUCCESSFULLY!")
                    }).then(() => {
                        dispatch({ type: refreshContextFromCache, payload: INITIAL_CONTEXT})
                    }).then(() => {
                        push('/');
                    })
                }).catch(err => console.log("AN ERROR OCCURRED", err))
            } else {
                console.log("EMAIL ALREADY EXISTS!!!!!!")
            }
    };

I set checkUserEmailExists to always return true. createUser is a firebase function in the cloud that is working to create new users. When this function is triggered, it is redirecting, then erroring.

The error says its a permissions error, but my firebase api key hasn't changed and I can amend existing records.

My db rules haven't changed either and are based on tokens, but the tokens are still working:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.token.admin == true;
      }
    match /{document=**} {
      allow create: if request.auth.token.coach == true;
      }
    match /sessions/{userId} {
      allow read, write: if request.auth.token.customer == true && request.auth.uid == userId;
      }
  }
}

Locally, before I push I called firebase use for the correct project in the firebase cli, and switched to the correct project with gcp locally too.

My firebaserc is like:

{
  "targets": {
    "prod": {
      "hosting": {
        "prod": [
          "prod-project"
        ]
      }
    },
    "develop": {
      "hosting": {
        "prod": [
          "prod-project"
        ]
      }
    },
    "prod-project": {
      "hosting": {
        "prod": [
          "prod-project"
        ]
      }
    },
    "ammonite-testing": {
      "hosting": {
        "prod": [
          "prod-project"
        ]
      }
    }
  },
  "projects": {
    "prod": "prod-project",
    "default": "prod-project"
  }
}

My firebase.json is like:

{
  "functions": {
    "source": "functions"
  },
  "hosting": {
    "target": "prod",
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

What is going on? If the firebase permissions aren't working? Why can I still save? Why has it broken on this latest ci build and not before?

question from:https://stackoverflow.com/questions/65952599/firebase-cant-create-new-doc

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As Renaud Tarnec mentioned your rules overlap each other. As explained in the Firestore documentation when multiple rules match a document the request is allowed if any of them is truthy. Actually the rules applied to a document in the sessions collection are:

match /sessions/{userId} {
    allow read, write: if request.auth.token.admin == true or
                          request.auth.token.coach == true or
    }                     (request.auth.token.customer == true && request.auth.uid == userId)

As per why the application did work before and isn't working now we cannot give an answer. Probably some part of the code changed and made the error surface, which in practice means that some requests fulfill one of the security criteria above and the others don't.

If you want to debug at this level one option might be to add logging code to this function and the Firebase function to see which claims were sent (admin, coach, userId, etc..).

Separately, the best practice when writing Firestore security rules would be to avoid overlapping rules entirely and grant access at the most fine-grained level possible. This helps protecting the data and making sure the access is restricted as desired, unexpected rules interactions are easy to miss.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...