Im thinking of using firebase real time database but there are a few things im afraid of:
There are a few things im thinking of doing:
Is this secure enough?
How can I secure my firebase from read / write exploits or ddos?
You general approach around the three steps is good practice.
Please consider Firebase is cloud based so its exposure is front and center to the world, here are some specific recommendations to firebase and how to introduce watch dog practises:
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this ruleset in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
{
"rules": {
"users": {
"$uid": {
".read": "auth.uid == $uid || root.child('users').child(auth.uid).child('isAdmin').val() == true",
".write": "root.child('users').child(auth.uid).child('isAdmin').val() == true",
".indexOn": ["email"]
}
}
}
}
IMHO - I would make this manual or atleast have it checked against the users registration IP against something like honeypot
const getCustomClaimsByEmail = require('../utilities/get-custom-claims-by-email');
const setCustomClaims = require('../utilities/set-custom-claims');
module.exports = ({ admin, environment }) => user => {
const db = admin.firestore();
const usersCollection = db.collection(environment.schema.users);
const customClaimsRef = admin.database().ref(environment.schema.customClaims);
const auth = admin.auth();
const email = extractEmailFromUser(user);
return Promise.resolve()
.then(getCustomClaimsByEmail(customClaimsRef, email))
.then(setCustomClaims(auth, user.uid))
.then(claims => {
const update = mapUserUpdate(claims, user);
return usersCollection.doc(user.uid).set(update, { merge: true });
});
};
function mapUserUpdate(claims, user) {
const email = extractEmailFromUser(user);
return {
claims,
email,
emailVerified: user.emailVerified,
lastSignInTime: user.metadata.lastSignInTime,
creationTime: user.metadata.creationTime,
providerData: user.providerData,
};
}
function extractEmailFromUser(user) {
return user.email || user.providerData.find(({ email }) => email).email;
}