am using firebase authentication, I refer this link
"users": {
".read": "auth != null && root.child('admins').child(auth.uid).val() == true",
".write": "auth != null && (root.child('admins').child(auth.uid).val() == true)",
"$uid": {
".read": "auth != null && (auth.uid == $uid || root.child('admins').child(auth.uid).val() == true)",
".write": "auth != null && (auth.uid == $uid || root.child('admins').child(auth.uid).val() == true)"
}
},
This is my firebase user table rules.
my services.js
signupUser: function(newUser) {
var secondaryApp = firebase.initializeApp(FirebaseAppConfig, "Secondary");
var usersRef = firebase.database().ref().child('users');
return secondaryApp.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then(function(firebaseUser) {
secondaryApp.auth().signOut();
var newUserWithoutPwd = _.extend({}, newUser);
delete newUserWithoutPwd.password;
return usersRef
.child(firebaseUser.uid)
.set(newUserWithoutPwd)
.then(function() {
return newUserWithoutPwd;
});
});
},
Authendication is success. But user table show in permission denied error.
Show below screen shot
My guess is that you want the newly created user to write their user profile to the database. In that case it is important that:
you write the profile data as the current user: firebase.database(secondaryApp).ref().child('users')
you don't sign out the user, until the writing is completed
In code:
signupUser: function(newUser) {
var secondaryApp = firebase.initializeApp(FirebaseAppConfig, "Secondary");
var usersRef = secondaryApp.database().ref().child('users');
return secondaryApp.auth()
.createUserWithEmailAndPassword(newUser.email, newUser.password)
.then(function(firebaseUser) {
var newUserWithoutPwd = _.extend({}, newUser);
delete newUserWithoutPwd.password;
return usersRef
.child(firebaseUser.uid)
.set(newUserWithoutPwd)
.then(function() {
secondaryApp.auth().signOut();
return newUserWithoutPwd;
});
});
},
Remove secondaryApp.auth().signOut();
Update this return firebase.database(secondaryApp).ref().child('users').
signupUser: function(newUser) {
var secondaryApp = firebase.initializeApp(FirebaseAppConfig, "Secondary");
return secondaryApp.auth()
.createUserWithEmailAndPassword(newUserInsert.email, newUserInsert.password)
.then(function(firebaseUser) {
var newUserWithoutPwd = _.extend({}, newUserInsert);
delete newUserWithoutPwd.password;
return firebase.database(secondaryApp).ref().child('users')
.child(firebaseUser.uid)
.set(newUserWithoutPwd)
.then(function() {
return newUserWithoutPwd;
});
});
},
Related
So, when I first open the connection with the database, all is working fine, but when I close it and try to re-open it, the db object gives no error but returns undefined ...
Here's how I open the connection :
let conn = null;
let db = null;
async function validateLoginForm(payload, res) {
const errors = {};
let isFormValid = true;
let message = '';
if (!payload || typeof payload.email !== 'string' || payload.email.trim().length === 0) {
if (payload.email !== 'anonymous') {
isFormValid = false;
errors.email = 'Please provide your email address.';
}
}
if (!payload || typeof payload.password !== 'string' || payload.password.trim().length === 0) {
if (payload.email !== 'anonymous') {
isFormValid = false;
errors.password = 'Please provide your password.';
}
}
let stringConnection = payload.email === 'anonymous' ? 'mongodb://ds133221.mlab.com:33221/sandbox-te' : 'mongodb://' + payload.email + ':' +
payload.password + '#ds133221.mlab.com:33221/sandbox-te';
conn = await MongoClient.connect(stringConnection, await function(err, dbase) {
if (err)
{
isFormValid = false;
let errorMessage = 'Error connecting to DB';
return res.status(400).json({
success: false,
message: errorMessage,
errors: errors
});
}
else
{
db = dbase;
if (payload.email !== 'anonymous')
{
let roles = dbase.command({usersInfo: {user: payload.email, db: 'sandbox-te'}, showCredentials: true}, (err, result) => {
if (result.users[0] && result.users[0].roles[0] &&
(result.users[0].roles[0].role === 'dbOwner' || result.users[0].roles[0].role === 'readWrite'))
{
dbase.close();
return res.status(200).json({
success: true,
hasWriteRole: true
})
}
});
}
else
{
return res.status(200).json({
success: true,
hasWriteRole: false
})
}
}
});
}
The first part of the file validates a login form and the second part uses the email and password to try to open a connection with the database.
The whole function just works fine, but when I try to re-open it in the same file but another function, it won't work :
router.post('/search', (req, res) => {
db.open((err, dbase) => {
let test = dbase.collection('test');
console.log(test);
let promiseOfFind = test.find({}).toArray((err, docs) => {
console.log(docs); // RETURNS UNDEFINED ONLY IF DB WAS CLOSED EARLIER
})
});
});
If I don't close the database in the validateLoginForm function, I can retrieve documents without having to open it again, but I just want to achieve this..
What is wrong with my code ? I'm pretty new to Javascript and the API reference of the official MongoDB driver for node.js doesn't help much..
I'm using latest versions of React, Express, MongoDB official Driver for Node.JS, and of course, Node.JS
Thanks in advance !
With MongoDB you should open a single connection and re-use it through your application. You don't need the promises you've got then.
So on startup:
const connection = MongoClient.connect(stringConnection, function(err, dbase) {
// Start web server
});
I have problems with read permission.
It will be helpfull if someone help me.
Note: the authentification work the user is loged...
Write permissions work but read permissions are denied.
I have this code:
{
"rules": {
"user":{
"$uid":{
".read": "auth.uid==$uid", // i try with ===
".write": "auth.uid==$uid" // i try with ===
}
}
}
}
This is the javascript code:
var userRef= db.ref().child("user/"+id);
userRef.on('child_added', data=>{
console.log(data.val());
});
userRef.on('child_changed', data=>{
console.log(data.val());
});
userRef.on('child_removed', data=>{
console.log(data.val());
});
function insertUser(){
db.ref("user/"+id).set({
email:email,
name:name
});
}
I also try with:
This make me a error on JavaScript
var userRef= db.ref("user").child(id);
I put ".read": true, but nothing happen yet!
I get the id in that way:
firebase.auth().onAuthStateChanged(
function(user){
if (user) {
if (user != null) {
user.providerData.forEach(function (profile) {
name = profile.displayName;
email = profile.email;
photoUrl = profile.photoURL;
id=user.uid;
var img = document.querySelector('#simg');
var p = document.querySelector('#p');
img.src=photoUrl;
p.innerHTML=name;
pemail.innerHTML=email;
});
}
}
Thanks!
I'm working on a site, using firebase
The security was:
{
"rules": {
"users": {
".read": true,
".write": true
}
}
}
So everyone can add their info, but none can access the main part.
But when someone now types this in the console:
ref = new Firebase("https://xxx.firebaseio.com/users");
ref.createUser({
email: email,
password: password
}, function(error, userData) {});
ref.authWithPassword({
email: email,
password: password
}, function(error, authData) {));
ref.remove();
all userdata will be removed.
All users have their own uid (e.g. simplelogin:58) and storageID (e.g. -Js18LFoT0SmFi2Iq4GP)
could I maybe do something with those? I really don't want anyone to be able to remove all of my user data, but I need to let the users edit their own info, and to remove their account when they'd like to.
Here's some of my code:
function register() {
var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
ref.createUser({
email: email,
password: password
}, function(error, userData) {
if (error) {
alert("Error creating user: " + error)
} else {
console.log("Successfully created user account with uid:", userData.uid);
var uid = userData.uid
var usersRef = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + uid)
var newUser = usersRef.set({
faveShow1: "",
faveShow2: "",
faveShow3: "",
faveShow4: "",
faveShow5: "",
faveShow6: "",
faveShow7: "",
faveShow8: "",
faveShow9: "",
faveShow10: "",
uid: uid
});
//var key = newUser.key();
//console.log(key)
login();
}
});
}
function login() {
clear();
var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
ref.authWithPassword({
email: email,
password: password
}, function(error, authData) {
if (error) {
alert("Login Failed!" + error);
} else {
console.log("Authenticated successfully with payload:", authData);
thisAuthData = authData.uid;
var usersRef = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + thisAuthData);
usersRef.on("value", function(snapshot) {
for (var i = 0; i < 1; i++) {
console.log(snapshot.val())
if (true) {
globalAuthData = snapshot.val();
//globalKey = amount;
var SS = snapshot.val()
show1 = SS.faveShow1;
show2 = SS.faveShow2;
show3 = SS.faveShow3;
show4 = SS.faveShow4;
show5 = SS.faveShow5;
show6 = SS.faveShow6;
show7 = SS.faveShow7;
show8 = SS.faveShow8;
show9 = SS.faveShow9;
show10 = SS.faveShow10;
//...//
}
}
}, function(errorObject) {
alert("The read failed: " + errorObject.code);
});
}
});
}
function removeUser() {
clear();
var ref = new Firebase("https://fiery-heat-xxx.firebaseio.com/");
var refSer = new Firebase("https://fiery-heat-xxx.firebaseio.com/users/" + thisAuthData)
ref.removeUser({
email: email,
password: password
}, function(error) {
if (error === null) {
alert("User removed successfully");
refSer.remove();
logoff();
} else {
console.log("Error removing user:", error);
}
});
}
function edit() {
clear();
var fredNameRef = new Firebase('https://fiery-heat-xxx.firebaseio.com/users/' + thisAuthData);
var onComplete = function(error) {
if (error) {
console.log('Synchronization failed');
} else {
console.log('Synchronization succeeded');
console.log(thisAuthData);
console.log(globalAuthData);
login();
}
};
if (document.getElementById("form1").value != "") {
var show1 = document.getElementById("form1").value;
}
var show2 = document.getElementById("form2").value;
var show3 = document.getElementById("form3").value;
var show4 = document.getElementById("form4").value;
var show5 = document.getElementById("form5").value;
var show6 = document.getElementById("form6").value;
var show7 = document.getElementById("form7").value;
var show8 = document.getElementById("form8").value;
var show9 = document.getElementById("form9").value;
var show10 = document.getElementById("form10").value;
fredNameRef.update({
faveShow1: show1,
faveShow2: show2,
faveShow3: show3,
faveShow4: show4,
faveShow5: show5,
faveShow6: show6,
faveShow7: show7,
faveShow8: show8,
faveShow9: show9,
faveShow10: show10,
}, onComplete);
}
function logoff() {
clear()
var ref = new Firebase('https://fiery-heat-xxx.firebaseio.com/')
ref.unauth();
//...//
}
}
and my securety rules:
{
"rules": {
"users": {
"$user_id": {
".write": "$user_id === auth.uid"
},
".read": true
}
}
}
But I can't register or update right now...
To make sure a user's information can only be edited by that user, you want to use auth.uid.
https://www.firebase.com/docs/web/guide/understanding-security.html
The most important built-in variable is auth. This variable is
populated after your user authenticates. It contains data about them
and auth.uid, a unique, alphanumeric identifier that works across
providers. The auth variable is the foundation of many rules.
{
"rules": {
"users": {
"$user_id": {
".write": "$user_id === auth.uid"
}
}
}
}
To make it a little more clear, auth.uid refers to the currently logged in user, and $user_id refers to the location in database. The $ points to the $location rule variable:
https://www.firebase.com/docs/security/api/rule/path.html
{ "rules": {
"users": {
"$user": {
".read": "auth.uid === $user",
".write": "auth.uid === $user"
}
}
}
}
When a user authenticates to a Firebase app, three things happen:
Information about the user is returned in callbacks on the client
device. This allows you to customize your app's user experience for
that specific user.
The user information returned contains a uid (a
unique ID), which is guaranteed to be distinct across all providers,
and to never change for a specific authenticated user. The uid is a
String that contains the name of the provider you're authenticating
with, followed by a colon and a unique id returned from the provider.
The value of the auth variable in your app's Security and Firebase
Rules becomes defined. This variable is null for unauthenticated
users, but for authenticated users it is an object containing the
user's unique (auth.uid) and potentially other data about the user.
This allows you to securely control data access on a per-user basis.
I wanna return the MySQL query in Node.js, but I got some problems.
Prob1. 'var userInfo' cannot get the value from function 'Authenticate()'
Prob2. The throw will be catched by 'dbclient.query', not my code you can see.
Hope guys can help me.
app.post('/create_member_check', function(req, res) {
var Authenticate = function () {
SearchUser(req.body.email, function (isExist) {
if (isExist === true)
throw 101;
else if (req.body.email === undefined || req.body.email == "")
throw 102;
else if (req.body.password === undefined || req.body.password == "")
throw 103;
else if (isExist === undefined)
throw 104;
var user = {
"email": req.body.email,
"password": req.body.password
};
AddUser(user);
// This line cannot return the 'user' for 'Authenticate()' caller.
return user;
});
}
try {
var userInfo = Authenticate();
}
catch (err) {
var userInfo;
if (err == 101)
userInfo = "[Error] This account already exists.";
else if (err == 102)
userInfo = "[Error] Please key in 'email'.";
else if (err == 103)
userInfo = "[Error] Please key in 'password'.";
else if (err == 104)
userInfo = "[Fatal Error] SearchUser return 'undefined'.";
}
res.render("login_system/create_member_check", {
layout: false,
pagename: "create",
authenticate: userInfo
});
});
SearchUser = function (email, callback) {
dbclient.query("SELECT * FROM user WHERE email = \"" + email + "\"", function (err, results) {
if (err || results.length <= 0)
callback(false);
else
callback(true);
});
}
Authenticate method can't be synchronous. You should make asynchronous method. Try this.
app.post('/create_member_check', function(req, res) {
var Authenticate = function (req, callback) {
SearchUser(req.body.email, function (isExist) {
if (isExist === true)
return callback(101);
else if (req.body.email === undefined || req.body.email == "")
return callback(102);
else if (req.body.password === undefined || req.body.password == "")
return callback(103);
else if (isExist === undefined)
return callback(104);
var user = {
"email": req.body.email,
"password": req.body.password
};
AddUser(user); //this is maybe asynchronous, again
callback(null, user);
});
}
Authenticate(req, function(err, user){
var userInfo;
if (err == 101)
userInfo = "[Error] This account already exists.";
else if (err == 102)
userInfo = "[Error] Please key in 'email'.";
else if (err == 103)
userInfo = "[Error] Please key in 'password'.";
else if (err == 104)
userInfo = "[Fatal Error] SearchUser return 'undefined'.";
res.render("login_system/create_member_check", {
layout: false,
pagename: "create",
authenticate: userInfo
});
});
});
And read this article ;)
I have a Node app with a Firebase db with security like this :
{
"rules": {
".read": true,
"albums": {
".write": "auth != null",
}
}
}
I login like this:
var firebaseTokenGenerator = require('firebase-token-generator'),
firebase = require('firebase');
var tokenGenerator = new firebaseTokenGenerator('my key');
var token = tokenGenerator.createToken();
var albumRef = new firebase('https://glowing-fire-8113.firebaseio.com/albums');
albumRef.auth(token, function(err) {
if(err) {
console.log("Authentication failed!");
} else {
console.log("Login succeeded!");
}
});
I get "Login succeeded!" printed to the console.
Then, later on I call this function:
var addAlbum = function(album, callback) {
if(album["album"] && album["artist"] && album["image"]) {
albumRef.push().set(album);
callback(null);
}
callback(new Error("Album JSON was missing some items"));
};
But, I get this printed out:
FIREBASE WARNING: set at /albums/-JMU95j8W4Vz3kchhNzL failed: permission_denied
What is going on here? Am I doing authentication incorrectly?
For reference, I'm using
"firebase" : "1.0.14",
"firebase-token-generator" : "0.1.4",