there is a web application built on Vue + Firebase. The question is how to automatically enter the application after the page is reloaded, how to later log in to your database, as far as I understand after authorization, all such data remains for example
fb.auth().onAuthStateChanged(user => {
console.log(user) // user profile
}
So I can get the user's email and uid, so firebase thinks I'm an authorized user, and allows me to edit and read data with rules:
".read": "auth != null",
".write": "auth != null"
However, on the Authentication tab, there is a field for each user "Last Login Date" and it is not updated until the "Normal" authorization by email password for example.
I'll repeat the question of how to authorize in my database after rebooting the page in the browser, is there any special method for this? Thank you in advance)
There is no way for your application code or configuration to affect when Firebase updates the Last Login Date. Well... you could require your user to re-authenticate, but I doubt that is what you want, and it can be bypassed by your users.
It sounds like you want to know when the user last started you application, which is something different from when they last logged in. To track when the user starts the application, consider using an analytics package.
Alternatively you can write a "lastSeen" value to the database whenever the onAuthStateChanged fires with a user profile. Something like this would do that for the Firebase Realtime Database:
firebase.database().ref("lastSeen").child(user.uid).set(firebase.database.ServerValue.TIMESTAMP);
Related
I am having a react application with firebase as authentication. My authentication code is below
await firebase.auth().onAuthStateChanged((user) => {
if (user) {
props.setUser(user); //setting the user if login/register happens
history.push(`/admin/dashboard`);
console.log("user",user)
} else {
props.setUser(null); //blocks the user to get into the app if he/she is not logged in
history.push("/");
}
});
So, when user logs in..he will be navigated to /admin/dashboard. suppose when am in /admin/home and when i refresh the page, it goes again to admin/dashboard which shouldn't happen. so I tried
history.push(${props.location.pathname}); it works correctly after the refresh, it stays on the same page when the application is logged in. but when I restart the server again when I try to log in, it says no redirect url is specified. Got stuck on this for a long time.. Any help is welcome.Thanks
What your code does is check if the user is logged in and only let the user access the data if so.
You should do that in the fireabse rules (= serverside) as this is way more secure.
You didn't provide the kind of FirebaseDB you are using. So assuming you use the Realtime Database here are some according rules:
{
“rules”: {
“.read”: “auth != null”,
“.write”: “auth != null”
}
}
You should maybe check the rules before deploying your app, because now every authenticated user can change/add/delete data, but you get the point. This does exactly what you want so you won't even need to perform a check in your ReactJS App. Firebase will automatically deny unauthenticated users the access to the database.
Btw: You should try to implement security relevant things in the Firebase Rules. Ideally you want your rules to be written in a way that you don't need to perform any validation inside your ReactJS app. Firebase rules can get quite complex. I experienced that myself when writing a chat app with chatrooms and everything. But it is definitly worth the effort if your app is more secure after.
I have managed to setup a custom login system using Firebase. The user enters email/password and is redirected to the main page(which is private). I am having issue with onAuthStateChanged after logging in. When I check the auth state after logging into the main page, i get invalid user (null). The firebase dashboard shows I have logged in successfully but onAuthStateChanged is the opposite.
I am trying to check if a user is logged in to my html pages, if not I want to redirect them to the login page. I like how the authentication works in firebase but I need to protect my html pages not my divs (which is what the vast majority of firebase auth tutorials show).
If anyone has an easier way to password protect a web directory that looks nicer than HTaccess, please advise (I am not crazy about using wordpress for password protection, but its an option). Otherwise, I guess I will have to do this in PHP. Thanks in advance!
(function () {
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
console.log(user);
console.log('A user is logged in.');
} else {
// No user is signed in.
console.log('Invalid user. Redirecting to root.');
window.location.replace('../index.html');
}
});
})();
If you navigate to a new page, Firebase will have to initialize again. As part of that it will try to restore the user's authentication state, but this requires a call to the server which takes time.
For that reason the onAuthStateChanged listener will initially fire with null as the current user (and auth.currentUser is set to null). Then once the user is signed in, the listener fires again with the user object for that user.
If you want to detect this initial state, you can either store some token value in the browser's local storage that you can check for yourself on the new page, or you could set a time-out for when you expect the user to be re-signed in and only then navigate away to the index.html page.
I'm building a CMS with Firebase, but struggling to assess whether what I require is possible, or if I'm missing something.
What I require is the ability to password-protect a page only, and remember that browser as having access. A full user account (using the in built auth) is required to edit the content of the page, but only a password is required to view it.
I know I can use the auth flow with email, but am looking for the editor to be able to create a password for viewing only.
Is this possible, or should I look elsewhere?
The way I commonly do this is a bit like Jeremy's answer, but simpler.
You ask the user for a password when they enter the page, and store that password locally (for reloads).
Then you store data in your database under a path that includes the password. So say that your password is geheim, you could store the data under:
data: {
geheim: {
value: "This is the secret value"
}
}
Now you secure your database with rules like these:
{
"rules": {
".read": false,
"data": {
"geheim": {
".read": true
}
}
}
}
Now somebody can only read the data at /data/geheim if they know the entire path. So you'll enter the data part in your code, but require them to enter geheim as the password. Then you attach a listener with:
firebase.database().ref("data").child(password).once("value", function(snapshot) {
console.log(snapshot.val());
});
And if the user entered the correct value for password, this will read the value.
Firebase Authentication only deals with authenticated user accounts. It doesn't deal with simple password protection of content.
It's definitely possible, but as Doug's answer indicated, you'll have to do it outside normal means. Off the top of my head, the way I would accomplish this is...
When a user enters a password, it stores the password in their local storage.
On page load, or on password entry... pull the password from local storage
Make a request to a Firebase cloud function, makes sure to include the password it just retrieved from local storage, and which page it is requesting content for
Firebase cloud function validates password
Firebase cloud function retrieves data for specific page
Firebase cloud function returns said data
Load data on front-end like normal
As you already identified, you should stick with the built-in Firebase auth for content editing.
I definitely suggest Frank's answer because it's simple and it works. Btw the moral of the story is that you use the firebase Database to store you view-only password but, if you want to complicate your life because you need a strong view-only password system, the Authentication product provides the custom authentication method that you can integrate with your existing auth system (for example fb login). It obviously needs a server-side implementation that is a code that takes the password, check if it's valid and sends the token back to the Auth system.
Here more details: https://firebase.google.com/docs/auth/web/custom-auth
My ionic app uses two firebase database instances. The rule allows everyone to read the data but requires the user to be authenticated in order to write to the database.
It works fine with the main database instance, but there is a problem with the second database instance: reading from it has no problem, BUT writing to the second database instance always error out with Permission Denied error.
If I change the rule to allow everyone to write, the second database instance will work as well. Here is what my rule looks like:
{
"rules" : {
"shuiyao" : {
".read": true,
".write": "auth != null"
}
}
}
I figured out the problem. Based on the rules, both of these two database instances require user to authenticate in order to have write access. Since each database is configured/connected with only one single app, I ended up having 'two apps' in my application. After adding this new database instance, I should have changed my code to authenticate with the second app in addition to the default app if the user needs write access to both database instances.
Currently, I'm working with a firebase application that only uses the Google auth provider. There is a single sign-in flow for new and returning users that calls
firebase.auth().signInWithPopup() to authenticate the user.
I want to populate an object on the firebase database that stores each new user's UUID and information about them. Ideally, I'd like to generate this information server side and not allow write access to the object from the client.
How can I best tell when a new user has signed up? I am passing the user's token to the server as a cookie to be authenticated with each request to make sure they're signed in and authorized. I could check the UUID of each request to see if it's already in the users object, but this seems hugely wasteful as the majority of requests will not be from new users.
modify rule of real time database:
"rules": {
"Users":{
"$uid":{
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
}
}
}