Is there a way in Firebase to check if you are authenticated? I could request a resource and catch the a 401 error but I'd like to avoid making the request if I already have authenticated.
Each Firebase reference has a way of getting the currently authenticated user.
For JavaScript you can call .getAuth().
var ref = new Firebase("<my-firebase-app>");
var authData = ref.getAuth();
if (authData !== null) {
// you're logged in
}
You can also listen for authenticate state change in realtime with .onAuth():
var ref = new Firebase("<my-firebase-app>");
ref.onAuth(function(authData) {
if (authData !== null) {
// you're logged in
}
});
Related
Hello here is my cloud code
Parse.Cloud.beforeSave(Parse.User,async (request)=>{
const user = request.object;
const t = user.get('tProfile');
const s = user.get('sProfile');
if (!t && !s) {
user.setACL(new Parse.ACL(user));
}else{
console.log('Old user detected');
}
});
As you can see I am trying to set Acl for a new user signing up with a before save handler, but the error that I get is UserID must be a string. So my question is how can I set an acl for a new user who is just signing up ? Thankyou
So i finally found a way to do so.
In the Before save handler just use this code :)
Parse.Cloud.beforeSave(Parse.User, async (request) => {
var newOjb = request.object;
if (!request.original) {
newOjb.setACL(new Parse.ACL(Parse.User.current()));
}
});
I am very new with firebase and javascript.
My project: Build a private messaging app. To do that, I want to define a sub collection in firestore for private messaging using the current user id and the destination user id.
Here is the function that allows this:
// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {
if (toUid === null) {
// If no destination user is definer, we set it to the below value
toUid = 'fixed_value';
};
const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};
My problem: I want to use the firebase.auth().currentUser.uid attribute, but it looks like the function is not waiting for firebase.auth initialization. How can I fix this problem?
Additional information:
I have two functions that are calling the first one (dmCollection):
// retrieve DMs
function messagesWith(uid) {
return dmCollection(uid).orderBy('sent', 'desc').get();
};
// send a DM
function sendDM(toUid, messageText) {
return dmCollection(toUid).add({
from: firebase.auth().currentUser.uid,
text: messageText,
sent: firebase.firestore.FieldValue.serverTimestamp(),
});
};
If I correctly understand your problem ("it looks like the function is not waiting for firebase.auth initialization"), you have two possible solutions:
Solution 1: Set an observer on the Auth object
As explained in the documentation, you can set an observer on the Auth object with the onAuthStateChanged() method:
By using an observer, you ensure that the Auth object isn't in an
intermediate state—such as initialization—when you get the current
user.
So you would modify your code as follows:
// retrieve DMs
function messagesWith(uid) {
return dmCollection(uid).orderBy('sent', 'desc').get();
};
// send a DM
function sendDM(toUid, messageText) {
return dmCollection(toUid).add({
from: firebase.auth().currentUser.uid,
text: messageText,
sent: firebase.firestore.FieldValue.serverTimestamp(),
});
};
// generate the right SubCollection depending on current User and the User he tries to reach
function dmCollection(toUid) {
if (toUid === null) {
// If no destination user is definer, we set it to the below value
toUid = 'fixed_value';
};
const idPair = [firebase.auth().currentUser.uid, toUid].join('_').sort();
return firebase.firestore().collection('dms').doc(idPair).collection('messages');
};
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
var messageText = '....';
sendDM(user.uid, messageText)
} else {
// No user is signed in.
}
});
Solution 2: Use the currentUser property
You could also "get the currently signed-in user by using the currentUser property" as explained in the same doc. "If a user isn't signed in, currentUser is null".
In this case you would do:
var user = firebase.auth().currentUser;
if (user) {
var messageText = '....';
sendDM(user.uid, messageText);
} else {
// No user is signed in.
// Ask the user to sign in, e.g. redirect to a sign in page
}
Which solution to choose?
It depends how you want to call the function(s) based on the user uid.
If you want to call the function(s) immediately after the user is signed in, use Solution 1.
If you want to call the function(s) at another specific moment (e.g. following a user action), use Solution 2.
I am using Firebase authentication in my iOS app. Is there any way in Firebase when user login my app with Firebase then logout that user all other devices(sessions)? Can I do that with Firebase admin SDK?
When i had this issue i resolved it with cloud functions
Please visit this link for more details https://firebase.google.com/docs/auth/admin/manage-sessions#revoke_refresh_tokens
Do the following;
Set up web server with firebase cloud functions (if none exists)
use the admin sdk(thats the only way this method would work) - [Visit this link] (
(https://firebase.google.com/docs/admin/setup#initialize_the_sdk).
Create an api that receives the uid and revokes current sessions as specified in the first link above
admin.auth().revokeRefreshTokens(uid)
.then(() => {
return admin.auth().getUser(uid);
})
.then((userRecord) => {
return new Date(userRecord.tokensValidAfterTime).getTime() / 1000;
})
.then((timestamp) => {
//return valid response to ios app to continue the user's login process
});
Voila users logged out. I hope this gives insight into resolving the issue
Firebase doesn't provide such feature. You need to manage it yourself.
Here is the Firebase Doc and they haven't mentioned anything related to single user sign in.
Here is what you can do for this-
Take one token in User node (Where you save user's other data) in Firebase database and regenerate it every time you logged in into application, Match this token with already logged in user's token (Which is saved locally) in appDidBecomeActive and appDidFinishLaunching or possibly each time you perform any operation with Firebase or may be in some fixed time interval. If tokens are different logged out the user manually and take user to authenticate screen.
What i have done is:
Created collection in firestore called "activeSessions".User email as an id for object and "activeID" field for holding most recent session id.
in sign in page code:
Generating id for a user session every time user is logging in.
Add this id to localstorage(should be cleaned everytime before adding).
Replace "activeID" by generated id in collection "activeSessions" with current user email.
function addToActiveSession() {
var sesID = gen();
var db = firebase.firestore();
localStorage.setItem('userID', sesID);
db.collection("activeSessions").doc(firebase.auth().currentUser.email).set({
activeID: sesID
}).catch(function (error) {
console.error("Error writing document: ", error);
});
}
function gen() {
var buf = new Uint8Array(1);
window.crypto.getRandomValues(buf);
return buf[0];
}
function signin(){
firebase.auth().signInWithEmailAndPassword(email, password).then(function (user) {
localStorage.clear();
addToActiveSession();
}
}), function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode === 'auth/wrong-password') {
alert('wrong pass');
} else {
alert(errorMessage);
}
console.log(error);
};
}
Then i am checking on each page if the id session in local storage is the same as "activeID" in firestore,if not then log out.
function checkSession(){
var db = firebase.firestore();
var docRef = db.collection("activeSessions").doc(firebase.auth().currentUser.email);
docRef.get().then(function (doc) {
alert(doc.data().activeID);
alert(localStorage.getItem('userID'));
if (doc.data().activeID != localStorage.getItem('userID')) {
alert("bie bie");
firebase.auth().signOut().then(() => {
window.location.href = "signin.html";
}).catch((error) => {
// An error happened.
});
window.location.href = "accountone.html";
} else{alert("vse ok");}
}).catch(function (error) {
console.log("Error getting document:", error);
});
}
PS: window has to be refreshed to log inactive session out.
I'm trying to get my current user after the login, but this returning null.
There's my code:
var currentUser;
firebase
.auth()
.onAuthStateChanged(function(user){
currentUser = user;
console.log(currentUser); //this returns my user object
});
console.log(currentUser); //this returns "undefined"
var otherCurrentUser = firebase.auth().currentUser;
console.log(otherCurrentUser); // this returns "null"
var otherCurrentUser = firebase.auth().currentUser;
This will return null because auth object has not been initialized, you need an observer to do that.
While Login, use observer and save the UID in localstorage, and while logout clear the localstorage
Observer
var currentUser;
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
currentUser = user.uid;
console.log(currentUser); //this returns my user object
window.localStorage.setItem("UID",currentUser);
} else {
currentUser = "Error"
console.log(currentUser); //this returns my user object
window.localStorage.setItem("UID",currentUser);
alert(" Error in your login code");
// No user is signed in.
}
});
After this, whenever you need to get the user id, just use
var getuid = window.localStorage.getItem("UID")
console.log(getuid) // will log the UID
While logout just remove it
window.localStorage.removeItem("UID");
Hope this helps..!
The onAuthStateChanged event fires whenever the user's authentication state changes. The user variable is only useful within that callback. You cannot transport it out of that function.
So all code that requires a user should be inside the callback:
var currentUser;
firebase
.auth()
.onAuthStateChanged(function(user){
currentUser = user;
console.log(currentUser); //this returns my user object
});
For more on this, see some of these:
Using variable outside of ajax callback function
How do I return the response from an asynchronous call?
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
Firebase Query inside function returns null
I'm trying to get started with firebase and now with the security part of it. I'm trying to keep it as simple as possible in order to get started, using guides and code snippets from the Firebase website.
In order to keep it simple I have a webpage containing a password (id "Code") and user input field (id "Door"). How do I check if the password entered in field "Code" is equal to the password that is already stored in node https://mydatabase.firebaseio.com/loapp_users/BAAJ/password, BAAJ being a userid of one of the users stored in node loapp_users, all with a child node "password"?
The code below doesn't seem to do the trick.
$(document).ready(function(){
// Monitoring User Authentication State
// Use the onAuth() method to listen for changes in user authentication state
// Create a callback which logs the current auth state
function authDataCallback(authData) {
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
} else {
console.log("User is logged out");
}
}
// Register the callback to be fired every time auth state changes
var ref = new Firebase("https://mydatabase.firebaseio.com");
ref.onAuth(authDataCallback);
$("#logout").click(
function logout() {
ref.unauth();
ref.offAuth(authDataCallback);
}
);
// LOGIN
// The code to authenticate a user varies by provider and transport method, but they all have similar signatures and
// accept a callback function. Use it to handle errors and process the results of a successful login.
// Create a callback to handle the result of the authentication
function authHandler(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
}
};
$("#login").click(
function() {
var usersRef = new Firebase("https://mydatabase.firebaseio.com/loapp_users");
// Authenticate users with a custom Firebase token
var _user = $("#Door").val();
var _level = "docent";
var _password = $("#Code").val();
var userRef = usersRef.child(_user);
// Attach an asynchronous callback to read the data at our user reference
userRef.on("value", function(snapshot) {
console.log(snapshot.val());
if (snapshot.val().child("password").text() == _password) {
ref.authWithCustomToken("eyJ0e....etc...mlhdCI6MTQyOTM4Mzc0M30.Vn1QF7cRC6nml8HB9NAzpQXJgq5lDrAie-zIHxtOmFk", authHandler);
} else {
console.log("Gebruikersnaam en code komen niet overeen")
}
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
}
);
});
snapshot.val().child("password").text()
should instead be:
snaphot.val().password
Then it works.