在部署到firebase时获得400,规则语法错误



当我运行`firebase部署'时,我会收到以下错误:

Error: HTTP Error: 400, Rules Syntax Error: undefined

这是我的规则。

{
  "rules": {
    "users": {
      "$id": {
        "account": {
          ".validate": "newData.hasChildren(['email', 'fullName']) && newData.child('fullName').val().matches(/^\w.*\w/)",
          "email": {
            ".validate": "newData.isString() && newData.val().matches(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$/i)"
          },
          "fullName": {
            ".validate": "newData.isString()"
          },
          "$other": {
            ".validate": "false"
          },
          ".write": "$id == auth.uid"
        }
      }
    },
    "quizzes": {
      "$id": {
        ".validate": "newData.hasChildren(['owner', 'created'])",
        "owner": {
          ".validate": "newData.isString()"
        },
        "created": {
          ".validate": "newData.isNumber()"
        },
        "rounds": {
          "$key1": {
            ".validate": "newData.hasChildren(['name', 'questionTime'])",
            "questions": {
              "$key2": {
                ".validate": "newData.isString() && newData.parent().parent().parent().parent().parent().parent().child('questions').child(newData.val()).val() != null"
              },
              ".validate": "newData.hasChildren()"
            },
            "name": {
              ".validate": "newData.isString()"
            },
            "questionTime": {
              ".validate": "newData.isNumber()"
            },
            "$other": {
              ".validate": "false"
            }
          },
          ".validate": "newData.hasChildren()"
        },
        "sessions": {
          "$key3": {
            ".validate": "newData.isString() && newData.parent().parent().parent().parent().child('sessions').child(newData.val()).val() != null"
          },
          ".validate": "newData.hasChildren()"
        },
        "$other": {
          ".validate": "false"
        },
        ".read": "data.child('owner').val() != null && data.child('owner').val() == auth.id || data.child('sessions').val() != null",
        ".write": "newData.child('owner').val() != null && newData.child('owner').val() == auth.uid"
      }
    },
    "questions": {
      "$id": {
        ".validate": "newData.hasChildren(['owner', 'details'])",
        "owner": {
          ".validate": "newData.isString()"
        },
        "details": {
          ".validate": "newData.hasChildren() && newData.hasChildren(['question', 'answer']) || newData.hasChildren() && newData.hasChildren(['question', 'correctAnswer']) || newData.hasChildren() && newData.hasChildren(['audioURL', 'title', 'artist']) || newData.hasChildren() && newData.hasChildren(['imageURL', 'question', 'answer'])",
          "question": {
            ".validate": "newData.isString() || newData.isString() || newData.isString()"
          },
          "answer": {
            ".validate": "newData.isString() || newData.isString()"
          },
          "$other": {
            ".validate": "false"
          },
          "answers": {
            "$key4": {
              ".validate": "newData.isString()"
            },
            ".validate": "newData.hasChildren()"
          },
          "correctAnswer": {
            ".validate": "newData.isString()"
          },
          "audioURL": {
            ".validate": "newData.isString()"
          },
          "title": {
            ".validate": "newData.isString()"
          },
          "artist": {
            ".validate": "newData.isString()"
          },
          "imageURL": {
            ".validate": "newData.isString()"
          }
        },
        "$other": {
          ".validate": "false"
        },
        ".write": "data.val() == null && newData.child('owner').val() == auth.uid || data.val() != null && newData.val() != null && data.child('owner').val() == auth.uid || data.val() != null && newData.val() == null && data.child('owner').val() == auth.uid"
      }
    },
    "sessions": {
      "$id": {
        ".validate": "newData.hasChildren(['quiz', 'created', 'currentRound']) && newData.parent().parent().child('quizzes').child(newData.child('quiz').val()).val() != null",
        "quiz": {
          ".validate": "newData.isString()"
        },
        "created": {
          ".validate": "newData.isNumber()"
        },
        "currentRound": {
          ".validate": "newData.isNumber()"
        },
        "$other": {
          ".validate": "false"
        },
        ".write": "data.val() == null && newData.parent().parent().child('quizzes').child(newData.val()).child('owner').val() == auth.uid || data.val() != null && newData.val() != null && newData.parent().parent().child('quizzes').child(data.val()).child('owner').val() == auth.uid || data.val() != null && newData.val() == null && newData.parent().parent().child('quizzes').child(data.val()).child('owner').val() == auth.uid",
        ".read": "true"
      },
      "$sid": {
        "participants": {
          "$pid": {
            ".validate": "newData.hasChildren(['name', 'score'])",
            "name": {
              ".validate": "newData.isString()"
            },
            "score": {
              ".validate": "newData.isNumber()"
            },
            "$other": {
              ".validate": "false"
            }
          }
        }
      }
    }
  }
}

这是从以下螺栓文件生成的:

path /users/{id}/account is UserAccount {
    write() {
        return id == auth.uid
    }
}
type UserAccount {
    email: Email
    fullName: String
    validate() {this.fullName.test(/^w.*w/)}
}
type Email extends String {
    validate(){
        return this.test(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i)
    }
}
path /quizzes/{id} is Quiz {
    write() {
        return this.owner !== null && this.owner == auth.uid
    }
    read() {
        return (this.owner != null && this.owner == auth.id) || this.sessions != null
    }
}
type Quiz {
    owner : String
    created : Number
    rounds : QuizRound[]
    sessions : SessionRef[]
}
type QuizRound {
    questions : QuestionRef[]
    name : String
    questionTime : Number
}
type QuestionRef extends String {
    validate() {
        root.questions[this] != null
    }
}
type SessionRef extends String {
    validate() {
        root.sessions[this] != null
    }
}
path /questions/{id} is Question {
    create() {
        return this.owner == auth.uid
    }
    update() {
        return prior(this.owner) == auth.uid
    }
    delete() {
        return prior(this.owner) == auth.uid
    }
}
type Question {
    owner : String
    details : TextQuestion | MultipleChoiceQuestion | SongQuestion | PhotoQuestion
}
type TextQuestion {
    question: String
    answer: String
}
type MultipleChoiceQuestion {
    question: String
    answers: String[]
    correctAnswer: String
}
type SongQuestion {
    audioURL: String
    title: String
    artist: String
}
type PhotoQuestion {
    imageURL : String
    question : String
    answer : String
}
path /sessions/{id} is Session {
    read() { true }
    create() {
        return root.quizzes[this].owner == auth.uid
    }
    update() {
        return root.quizzes[prior(this)].owner == auth.uid
    }
    delete() {
        return root.quizzes[prior(this)].owner == auth.uid
    }
}
type Session {
    quiz : String
    created : Number
    currentRound : Number
    validate() {
        root.quizzes[this.quiz] != null
    }
}
path /sessions/{sid}/participants/{pid} is Participant {
}
type Participant {
    name : String
    score : Number
}

将生成的代码粘贴到火箱控制台中,并尝试上传它,给了我一个更明显的错误:

Error saving rules - Line 141: Cannot have multiple default rules ('$id' and '$sid')

在生成的输出中,我在 sessions": $ id and $ sid"下有2个通配符位置,因为在我的螺栓路径中,我在2个路径中使用了2个不同的变量名称。

最新更新