Firebaseのrulesをテストしようとしていたのですが、エミュレータを起動して、npm test
を実行すると、以下のエラーが発生しました。
FirebaseError: 7 PERMISSION_DENIED: false for 'create' @ L71
@ L71
がline 71のことだとしたら、firestore.rulesファイルの71行目は
allow create: if isUserAuthenticated(userId) && isValidUserCreate(request.resource.data, userId);
です。(下記にコードを記載しています。)
参考しにた記事はこちらです。
そして、以下がテストコードになります。
rules.test.ts
1import * as firebase from "@firebase/rules-unit-testing"; 2import { TokenOptions } from "@firebase/rules-unit-testing/dist/src/api"; 3import { readFileSync } from "fs"; 4 5const projectId = "rule-test"; 6process.env.FIRESTORE_EMULATOR_HOST = "localhost:8080"; 7 8function getAuthFirestore(auth: TokenOptions) { 9 return firebase.initializeTestApp({ projectId, auth }).firestore(); 10} 11 12describe("firestore security test", () => { 13 beforeAll(async () => { 14 await firebase.loadFirestoreRules({ 15 projectId, 16 rules: readFileSync("firestore.rules", "utf8"), 17 }); 18 }); 19 20 afterEach(async () => { 21 await firebase.clearFirestoreData({ projectId }); 22 }); 23 24 afterAll(async () => { 25 await Promise.all(firebase.apps().map((app) => app.delete())); 26 }); 27 28 describe("ユーザー読み書きテスト", () => { 29 it("usersのデータは、ユーザ本人のみ書き込み可能", async () => { 30 const firestore = getAuthFirestore({ uid: "user" }); 31 const ref = firestore.collection("users").doc("user"); 32 await firebase.assertSucceeds(ref.set({ username: "サンプル" })); 33 34 const otherUserRef = firestore.collection("users").doc("userB"); 35 await firebase.assertFails(otherUserRef.set({ username: "サンプル" })); 36 }); 37 }); 38}); 39
また、以下はruleのコードになります。
firestore.rules
1rules_version = '2'; 2service cloud.firestore { 3 match /databases/{database}/documents { 4 5 function isAnyAuthenticated() { 6 return request.auth != null; 7 } 8 9 function isUserAuthenticated(userId) { 10 return isAnyAuthenticated() && userId == request.auth.uid; 11 } 12 13 function isValidUserCreate(user, targetUserId) { 14 return user.size() == 3 15 && 'email' in user && user.email is string 16 && 'username' in user && user.username is string 17 && 'uid' in user && user.uid is string && user.uid == targetUserId; 18 } 19 20 function isValidUserUpdate(user, targetUserId) { 21 return user.size() == 3 22 && 'email' in user && user.email is string 23 && 'username' in user && user.username is string 24 && 'uid' in user && user.uid is string && user.uid == targetUserId; 25 } 26 27 function isValidBookmarkAdd(bookmark) { 28 return bookmark.size() == 6 29 && 'authorName' in bookmark && bookmark.authorName is string && bookmark.authorName.size() > 0 30 && 'content' in bookmark && bookmark.content is string && bookmark.content.size() > 0 31 && 'createdAt' in bookmark && bookmark.createdAt is string 32 && 'id' in bookmark && bookmark.id is string 33 && 'saveId' in bookmark && bookmark.saveId is string 34 && 'title' in bookmark && bookmark.title is string && bookmark.title.size() > 0 35 } 36 37 function isValidBookmarkUpdate(bookmark) { 38 return bookmark.size() == 6 39 && 'authorName' in bookmark && bookmark.authorName is string && bookmark.authorName.size() > 0 40 && 'content' in bookmark && bookmark.content is string && bookmark.content.size() > 0 41 && 'createdAt' in bookmark && bookmark.createdAt is string 42 && bookmark.createdAt == resource.data.createdAt 43 && 'id' in bookmark && bookmark.id is string 44 && 'saveId' in bookmark && bookmark.saveId is string 45 && 'title' in bookmark && bookmark.title is string && bookmark.title.size() > 0 46 } 47 48 function isValidPostCreate(post) { 49 return post.size() == 6 50 && 'authorName' in post && post.authorName is string && post.authorName.size() > 0 51 && 'content' in post && post.content is string && post.content.size() > 0 52 && 'createdAt' in post && post.createdAt is timestamp 53 && 'category' in post && post.category is string 54 && 'uid' in post && post.uid is string 55 && 'title' in post && post.title is string && post.title.size() > 0 && post.title.size() <= 42 56 } 57 58 function isValidPostUpdate(post) { 59 return post.size() == 7 60 && 'authorName' in post && post.authorName is string && post.authorName.size() > 0 61 && 'content' in post && post.content is string && post.content.size() > 0 62 && 'createdAt' in post && post.createdAt is timestamp 63 && 'category' in post && post.category is string 64 && 'id' in post && post.id is string 65 && 'uid' in post && post.uid is string 66 && 'title' in post && post.title is string && post.title.size() > 0 && post.title.size() <= 42 67 } 68 69 match /users/{userId} { 70 allow get: if isUserAuthenticated(userId) || isAnyAuthenticated(); 71 allow create: if isUserAuthenticated(userId) && isValidUserCreate(request.resource.data, userId); 72 allow update: if isUserAuthenticated(userId) && isValidUserUpdate(request.resource.data, userId); 73 74 match /bookmarks/{bookmarkId} { 75 allow read: if isUserAuthenticated(userId); 76 allow create: if isUserAuthenticated(userId) && isValidBookmarkAdd(request.resource.data); 77 allow update: if isUserAuthenticated(userId) && isValidBookmarkUpdate(request.resource.data); 78 allow delete: if isUserAuthenticated(userId); 79 } 80 } 81 82 match /posts/{postId} { 83 allow read: if isUserAuthenticated(request.auth.uid); 84 allow create: if isUserAuthenticated(request.auth.uid) && isValidPostCreate(request.resource.data); 85 allow update: if isUserAuthenticated(request.auth.uid) && isValidPostUpdate(request.resource.data); 86 allow delete: if isUserAuthenticated(request.auth.uid); 87 } 88 } 89}
実現したいこと
・エラーを解消する
・testをpassすること
です。
auth関連のところで何かうまくいってなさそうなのはわかるのですが、調べてもいい感じの答えに辿り着けず、質問させていただきました。
環境
テストに使っているツールは、@firebase/rules-unit-testing
です。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/12/14 04:06