Firebase Restrict Access to other pages without user logged in - javascript

I have an index.html page that will redirect to home.html after the correct login. I have solved the login and logout part. my problem is I can access home.html directly on the URL without logging in.
here is some snippet of my home.html
<script>
var config = {
apiKey: "xxxxxx",
authDomain: "firebaseapp.com",
databaseURL: "firebaseio.com",
};
firebase.initializeApp(config);
const auth=firebase.auth();
const db=firebase.database();
var user = firebase.auth().currentUser;
if (user) {
//blank if correct login
} else {
window.location.href = 'firebaseapp.com/index.html';
}
</script>
I put this on the beginning of my home.html so that if the page will be accessed directly it will return to the index. It worked on redirecting to the index.html BUT even when i login correctly, it still redirects me to the index.html
It seems like the firebase gets the auth too fast that it cannot initialize the currentUser values properly thus giving a null result. Any suggestion on how to restrict direct access using the URL would really help.
Thanks!

try using firebase.auth().onAuthStateChanged instead of firebase.auth().currentUser; it is the recommended way to get the current user.
Getting the user by currentUser may cause a problem similar to what you are seeing. This is from the official doc of firebase.
Note: currentUser might also be null because the auth object has not finished initializing. If you use an observer to keep track of the user's sign-in status, you don't need to handle this case.
Try to get the current user like this:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});

I'm not that experienced jet, but this has worked for me, but I'm not sure if it is the best way. I simply gave my body an id and added this JavaScript code:
var auth = firebase.auth();
auth.onAuthStateChanged(function(user) {
if (user) {
document.getElementById('homeBody').style.visibility = "visible";
} else {
document.getElementById('homeBody').style.visibility = "hidden";
}
});
I think this will do it for the starting companies. As your business grows, I recommend that you consider taking more security

Related

Getting Uncaught TypeError in Firebase Auth get current user email

I am trying to get the email of the currently signed in user in my Firebase app, but it keeps giving me an error.
This is my code for getting the current user email:
user_email = firebase.auth().currentUser.email
The error that I get is:
Error Image
It looks like firebase.auth().currentUser is null at the time when your firebase.auth().currentUser.email runs. This is quite common, as Firebase refreshes the user's authentication state when the page loads, and this requires it to make an asynchronous call to the server.
For this reason, you should not assume there is a user signed in. You should either put a check around your current code:
if (firebase.auth().currentUser) {
user_email = firebase.auth().currentUser.email
}
Or (and often better) you should use a so-called auth state listener, to have your code automatically respond to changes in the user's authentication state. From the Firebase documentation on getting the currently signed-in user, that'd be:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
user_email = firebase.auth().currentUser.email;
// TODO: execute code that needs `user_email`
} else {
// User is signed out
// ...
}
});

VueJS + Firebase Authentication Can't Access Session Before Scripts Load

So i'm working on a project and i'm struggling a bit...
I'm using VueJS for the frontend and Firebase Authentication to log users in.
I'm trying to determine whether a user is currently logged in or not using firebase.auth().currentUser;
(If returns null then no user is logged In) Sounds simple right!?
I'm running the currentUser() in my vueJS created() function. However, running firebase.auth().currentUser; here seems to always return null. But however, if i use a set timeout method then it is able to fetch the users data. It looks to me like vue is trying to fetch the data before it has loaded in.
I hope this isn't too hard to understand - i'm quite new to Vue and firebase!
Please find snippets of my code attached below.
Vue.config.devtools = true;
var app = new Vue({
el: '#app',
data: {
user: '',
loggedIn: false
},
created() {
var user = firebase.auth().currentUser;
if (user != null){
this.user = user;
this.loggedIn = true;
} else {
this.loggedIn = false;
}
}
})
Below are the firebase scripts i'm loading at the bottom of the page body
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.15.5/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.14.1/firebase-analytics.js"></script>
<script src="js/firebaseConfig.js" type="text/javascript"></script>
Essentially, how can i fix this without using a setTimeout() method? and also how does firebase get this session, which script handles this?
firebase.auth().currentUser always returns null when the page is first loaded. It will only contain an actual user object after the SDK has determined that the user is actually signed in. There is no guarantee exactly how long that will take.
The preferred way to find out when that happens is to use an auth state observer, as shown in the documentation.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
// ...
} else {
// User is signed out.
// ...
}
});
You can use this callback to determine when it's time to render content for that individual user.
I suggest also reading more about the behavior of the Firebase Auth SDK in this blog.
async created() {
var user = await firebase.auth().currentUser;
if (user != null){
this.user = user;
this.loggedIn = true;
} else {
this.loggedIn = false;
}
}

Firebase initialize app lose Current User

I have a web application using html-js-css and a flask server.
My web app is a multi-pages app which apparently means that I have to Initialize firebase for each page in which i want to use it -.-
The problem is that every time I initialize firebase app, I lose the current user so while in my main page, after log-in, if I write:
const USER = firebase.auth().currentUser;
console.log(USER.uid);
I get my user ID, as soon as I move to another page and repeat the above code, I get the error:
TypeError: USER is null
Is there a way to either:
avoid Initializing the firebase-app at avery page
keep the CurrentUser (even storing it securely somewhere)
Thank you
Workaround:
I got this workaround working before Frank answer which is probably the best way to proceed. Instead I just stored the user id in an encrypted variable accessible to all pages.
Since the main.html page is always loaded, I store/removed the variable in a onAuthStateChanged listener there so as soon as the user is logged out, that variable is removed:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
cached_uid = JSON.stringify(user.uid);
cached_uid = btoa(cached_uid);
localStorage.setItem('_uid',cached_uid);
} else {
localStorage.removeItem('_uid');
}
});
then on the other pages:
function loadUID(){
var uid = localStorage.getItem('_uid');
if (!uid) return false;
uid = atob(uid);
uid = JSON.parse(uid);
return uid
}
I followed this to find this solution:
How to send variables from one file to another in Javascript?
You will need to initialize the Firebase app on each page, but that is supposed to be a fairly cheap operation.
To pick up the user on the new page, Firebase runs a check against the server to ensure the user token is still valid. Since this code calls a server, its result likely isn't available yet when your firebase.auth().currentUser runs.
To solve this, run the code that requires a user in a so-called auth state change listener:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
Also see the Firebase documentation on getting the currently signed in user.

Keep user after redirect with firebase

Im currently working on a side project with firebase on web and it uses user auth. I have the user logging in and then creating a game room which redirects to a separate page for the game "room". After the page redirects though i cannot pull any of the users data and the only way that im doing it is by re initializing firebase and using
auth.onAuthStateChanged(function(user) {
if (user && user != null) {
uid = user.uid;
email = user.email;
currUser = user;
} else {
//user isnt logged in
window.location.href = 'index.html';
}
There seems to probably be an easier way to do this but i cant seem to get it working and this way also messes up sections of my other code.
Attaching an onAuthStateChanged callback is the idiomatic way to get the user.
You can also get the user with firebase.auth().currentUser. But if a token refresh is required, you may in that case mis-detect that there is no user. That why an onAuthStateChanged callback is recommended.
See the Firebase documentation on getting the current user.

How to handle user information using firebase simple login for facebook

I am building a webpage using AngularJS and Firebase. I want to use facebook login to connect information on the webpage with the user. Firebase has a version of simple login which I guess is supposed to simplify the login process.
My problem is that I want to access information about the logged in user in a lot of places on my webpage but I can't find a good way to do it.
This is how I started out:
var userInfo = null;
var ref = new Firebase('https://<yourfirebase>.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(ref, function(error, user) {
if(error)
alert("You are not logged in");
else if(user)
{
//store userinfo in variable
userInfo = user;
}
else
//user logged out
});
//do something with userInfo
alert(userInfo.name);
My first thought was to run this at the top of my page and then use the info about the user. The problem is that the code using userInfo (as in e.g. the alert) will always run before the userInfo variable has been filled and userInfo will return undefined/null.
I then proceeded to always create a new firebasesimplelogin object when i want to retrieve user data. Which of course isn't very good. Especially since every created FirebaseSimpleLogin object will be called again whenever another is called or a user logs out, for example.
So my question is, how do I use FirebaseSimpleLogin to handle and use my user information in the best way?
I would have liked some function to getUserInfo() or check isLoggedIn() for example. How do you do this properly?
You can take a look at this example for thinkster. It's based on using simple login with userid/password. http://www.thinkster.io/angularjs/4DYrJRxTyT/7-creating-your-own-user-data-using-firebase.
You can create a function like getLoggedinUser that runs in $rootScope that will allow you to find the user throughout the application.
UPDATE:
Around the middle of October 2014, firebase made some big changes. This method might still work, but it's better to take advantage of the newer version of firebase, specifically getauth and onauth. These methods will allow you to do the same thing without running on the rootScope. https://www.firebase.com/docs/web/guide/user-auth.html#section-login
Please make a constant to use it everywhere in your App like that
.constant('facebookUrl', 'https://rjrestaurantapp.firebaseio.com');
Then in the controller inject this constant "facebookUrl & "$state" as shown below...
.controller('loginCtrl', function($scope,facebookUrl,$state){
and then you only need to give name of the state where you want to redirect after facebook authentication..
var ref = new Firebase(facebookUrl);
$scope.fbLogin = function () {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
$state.go('restaurant');
}
})
}})
You can see the information in authData object after successfull authentication using facebook ....
please read this doc carefully https://www.firebase.com/docs/web/guide/login/facebook.html
The above is the example of simple login using firebase and for retrieving data for each logged in user, you have to store user information at the time of signin as you know that firebase makes every child with a unique ID .. then you only need to use the offline features of firebase that will find which user is offline and according to that remove the node with the same ID which one is offline, you can find examples in the MANAGING PRESENCE section of the below link ..
https://www.firebase.com/docs/web/guide/offline-capabilities.html

Categories