5 Firestore Rule yang Sering Dipakai dan Cara Pengunaannya

Bayu Setiawan
SkyshiDigital
Published in
3 min readJul 8, 2021

Pendahuluan

Hello, selamat pagi, siang, sore, dan malam sahabat coders.

Security rules merupakan bagian yang penting dalam memakai database firestore, hal ini dikarenakan dalam menggunakan firestore, user/client dapat mengakses database firestore secara langsung, apabila database firestore kita memiliki rule yang mengizinkan semua orang mengakses data secara bebas maka semua orang dapat: membaca, mengganti, ataupun menghapus semua data di firestore kita. Sedangkan jika kita tidak mengizinkan orang untuk mengakses semua data maka kita harus menyediakan akses lewat hal lain seperti REST API, dan semua pembatasan akses akan dihandle oleh implementasi API, akan tetapi hal tersebut membuat kita tidak dapat memanfaatkan semua fitur yang ditawarkan oleh firestore seperti: realtime data, offline access dan lain-lain.

Nah,,, pada kesempatan kali ini saya ingin berbagi semua security rule firestore yang sering saya gunakan. Mari kita mulai dari rule yang pertama.

1. Hanya untuk user yang sudah login

function isSignedIn() {
return request.auth != null;
}

Rule yang pertama adalah untuk mengijinkan akses kepada user yang sudah berhasil login, contoh penerapan rule ini adalah: Collection pengumuman yang hanya dapat dibaca oleh user yang sudah login.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /announcements/{id} {
allow read: if isSignedIn();
}
// functions
function isSignedIn() {
return request.auth != null;
}
}
}

2. Hanya untuk owner

function isOwner(userId) {
return request.auth.uid == userId;
}

Terkadang kita menginginkan user hanya bisa membaca data miliknya saja yang ditandai dengan userId user tersebut. Biasanya rule ini diterapkan di collection yang menyimpan data user, pada collection users hanya dapat mengakses datanya saja, dan tidak bisa mengakses data orang lain ataupun melakukan list semua data.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow get: if isOwner(userId);
}
// functions
function isOwner(userId) {
return request.auth.uid == userId;
}
}
}

3. Hanya untuk user yang memiliki custom claim tertentu

function userHaveClaim(claim){
return request.auth.token[claim];
}

Custom claim merupakan salah satu cara agar kita dapat memberikan hak akses pada suatu user, untuk memberikan user custom claim dapat dibaca disini.Terkadang kita ingin suatu data hanya bisa diakses ataupun diubah jika user punya custom claim tertentu. Contoh nya suatu user punya custom claim seperti berikut ini

{
"isAdmin": true
}

Contohnya pada collection transaksi di nomor 2 tadi, kita dapat menambahkan rule bahwa admin dapat mengakses dan mendelete suatu transaksi

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /transactions/{transactionId} {
allow read: if isOwner(resource.data.userId) || userHaveClaim("isAdmin");
}
// functions
function isOwner(userId) {
return request.auth.uid == userId;
}
function userHaveClaim(claim){
return request.auth.token[claim];
}
}
}

4. Hanya boleh update field tertentu

function isOnlyUpdateField(fields) {
return incomingData().diff(existingData()).affectedKeys().hasOnly(fields);
}

terkadang kita ingin suatu user hanya mengupdate field-field tertentu. Contohnya ketika kita ingin user hanya bisa mengupdate flag isRead pada notifikasi, tentu saja user hanya boleh update notifikasi miliknya saja.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId}/notifications/{notificationId} {
allow read: if isOwner(userId);
allow update: if isOwner(userId) && isOnlyUpdateField(["isRead"])
}
// functions
function isOwner(userId) {
return request.auth.uid == userId;
}
function isOnlyUpdateField(fields) {
return request.resource.data.diff(resource.data).affectedKeys().hasOnly(fields);
}
}
}

5. Tidak boleh update field tertentu

function notUpdating(field) {
return !(field in request.resource.data) || resource.data[field] == request.resource.data[field];
}
function notWriting(field) {
return !(field in incomingData());
}

Rule ini merupakan kebalikan dari rule nomor 4, pada rule ini kita ingin user untuk tidak mengupdate/menulis field secara langsung. Contohnya pada collection user, semua user memiliki attribute balance yang berisi saldo yang dimiliki user, tentu saja user hanya boleh membaca nilai dari saldo ini akan tetapi tidak boleh menulis ataupun mengupdate nilai dari saldo.

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow get: if isOwner(userId);
allow update: if isOwner(userId) && notUpdating("balance");
allow create: notWriting("balance");
}
// functions
function isOwner(userId) {
return request.auth.uid == userId;
}
function notUpdating(field) {
return !(field in request.resource.data) || resource.data[field] == request.resource.data[field];
}
function notWriting(field) {
return !(field in incomingData());
}
}
}

Penutup

Itu tadi adalah semua rule yang sering saya gunakan untuk mengamankan database firestore, jika terdapat tambahan silahkan tulis di kolom komentar ya, terimakasih sudah membaca.

--

--

Bayu Setiawan
SkyshiDigital

Currently work at Skyshi as Backend Programmer. Have a keen interest on tools that make my work easier.