When I refresh my page Firebase authData becomes null - angularjs

var user = null;
this.showLoginDialogGoogle = function(){
var ref = new Firebase("https://googlelogin1.firebaseio.com");
ref.authWithOAuthPopup("google", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
console.log("Authenticated successfully with payload:", authData);
user = authData;
This.goToPage('/profile');
$rootScope.flag=true;
$rootScope.$digest();
}
});
};
I have authenticated the user with firebase google authentication. The problem is when I refresh my page, my session expires and authData becomes null. What can I do so that after refreshing the page my authData remains with the data it got at the time of authentication?

You'll want to monitor authentication state:
// Register the callback to be fired every time auth state changes
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(function authDataCallback(authData) {
if (authData) {
console.log("User " + authData.uid + " is logged in with " + authData.provider);
} else {
console.log("User is logged out");
}
});
Note that you're not using the AngularFire authentication wrappers. While your approach will authenticate the user, you will have to notify Angular of the updated scope yourself (see $timeout()). If you'd rather not do that yourself, look at AngularFire's auth wrappers, specifically $onAuth()

Related

Using $scope in AngularJS to change value at index.html in routing

I'm making a single page app in AngularJS using Firebase and using the side nav bar on index.html.
And after login, I want the username should be on the side nav bar but the $scope is working for the current page on the controller is working.
scotchApp.controller('mainController', function($scope) {
$scope.validateLogin = function()
{
var email = $scope.login.userName + "#xyz.co";
var password = $scope.login.password;
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
$scope.message = "please enter the correct details";
});
firebase.auth().onAuthStateChanged(function(user)
{
if(user)
{
$scope.usermobile = $scope.login.userName;
window.location.assign("/#/equipment");
}
});
}
$scope.message = '';
});
The current user is available in firebase.auth().currentUser as described in the docs so in your mainController you don't need to listen for auth changes.
In your code you are attaching a new listener each time the user tries to login, but what you actually want is to respond to one successful login, so just add a then to your sign in call:
firebase.auth().signInWithEmailAndPassword(email, password)
.then(function (user) {
console.log('the logged in user: ', user);
// Go to the other route here.
// It is recommended to use the router instead of "manually" changing `window.location`
})
.catch(function(error) {
$scope.message = "please enter the correct details";
});

Logout with Firebase

I am trying to do a user auth, and I am in the part of the logout now
<button ng-click="logOut(user)">
GOING OUT
</button>
here is how they sign in
$scope.signIn = function (user) {
$scope.signInErrorShow = false;
if (user && user.email && user.pwdForLogin) {
auth.$authWithPassword({
email: user.email,
password: user.pwdForLogin
}).then(function (authData) {
console.log("Logged in as:" + authData.password.email);
ref.child("users").child(authData.uid).once('value', function (snapshot) {
var val = snapshot.val();
$scope.$apply(function () {
$rootScope.displayName = val;
});
});
$scope.userLogin = true;
$ionicLoading.hide();
$scope.closeModal();
$rootScope.$broadcast('');
}).catch(function (error) {
$ionicLoading.hide();
});
} else
$scope.signInErrorShow = true;
};
and I am trying to call logOut
$scope.logOut = function(user) {
ref.unauth();
};
once I call log out, I don't see any post or get in the Network section of the browser.
In the Firebase Docs, all they say about log out is this
Logging Users Out
Calling unauth() invalidates the user's token and logs them out of your application:
Copy
ref.unauth();
If you had previously used the onAuth() method to listen for authentication state, your callback would now be invoked with null for authData.
so what should I do here ?
Concerning logout not showing any network activity: on login firebase probably gives you an access token (kept by the firebase client script) when you login.
When after login your application accesses firebase it adds this token to the header of your requests (authorization header?).
When you logoff the firebase client script simply erases the token. This way the firebase backend doesn't have to keep session state on their (distributed) servers. They only have to check the validity of the token sent in each request.

Firebase Angular OAuth with Google email scope, auth.$authWithOAuthPopup vs ref.authWithOAuthPopup

I'm successfully using Firebase's angular library to auth users against Facebook and Google, but I'm having troubling retrieving the user's email when using firebaseAuth's $authWithOAuthPopup.
Here's my login function.
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseAuth(ref);
loginGoogle: function () {
console.log('Logging in Google.');
return auth.$authWithOAuthPopup('google', function(error, user){
//TODO: Handle Failed login better
console.log('Google login failed');
console.log(error);
},{
scope: 'email'
});
};
This will pop up the google auth window and log in successfully. But, in the access permissions window, it doesn't request the 'email' scope access.
If I use ref.authWinOAuthPopup(...) instead of auth.$authWithOAithPopup(...) it does properly request the email perms, and delivers that info after auth.
Am I doing something wrong here? Or, is it an Angularfire bug that I should be reporting?
Angularfire v0.9.2.
After digging in further I found that the $firebaseAuth.$authWithOAuthPopup takes only two arguments (provider and options), whereas the Firebase.authWithOAuthPopup takes three (provider, onComplete callback, options). So, using refactoring to use the returned promise instead of passing in a callback function fixed the issue.
To be more clear, I'd like to add my snippets to show how to pass the e-mail scope to google oAuth.
As you mentioned, if you're using the promise to do the authentication instead of the callback you can pass the option for the email scope to the auth. call as second parameter and then the e-mail address will be available in the payload.
Please have a look at the following snippet:
$scope.loginGoogle = function() {
Auth.$authWithOAuthPopup("google", {scope: ['email']}).then(function(authData) {
// handle authData in onAuth handler in app.js in run method with Auth.$onAuth(function(authData) { ... });
console.log("Authenticated successfully with payload:", authData);
$location.path(REDIRECT_ROUTE);
})
.catch(function(err) {
$scope.err = errMessage(err);
});
};
function errMessage(err) {
var msg = "";
//return angular.isObject(err) && err.code? err.code : err + '';
switch (err.code) {
case "INVALID_EMAIL":
case "INVALID_PASSWORD":
case "INVALID_USER":
console.log("The specified user account email is invalid.");
msg = "E-mail or password is invalid.";
break;
/*
case "INVALID_PASSWORD":
console.log("The specified user account password is incorrect.");
break;
case "INVALID_USER":
console.log("The specified user account does not exist.");
break;
default:
// password or email empty;
console.log("Error logging user in:", err);*/
};
return msg;
}
angular.module('firebase.auth', ['firebase', 'firebase.utils'])
.factory('Auth', ['$firebaseAuth', 'fbutil', function($firebaseAuth, fbutil) {
return $firebaseAuth(fbutil.ref());
}]);
This is what I did and it worked for me
.config(function ($firebaseRefProvider) {
$firebaseRefProvider.registerUrl('https://****.firebaseio.com/');
})
Then in controller
loginWithGoogle: function(){
var ref = $firebaseRef.default;
ref.authWithOAuthPopup("google", function(error, authData) {
if (error) {
...
} else {
console.log(authData.google.email);
}
},{scope: 'email'});
}

How to prevent new anonymous authentication UID after browser refresh in Firebase

I am using anonymous authentication in Firebase with Angular. The goal is to have one UID associated with a user until the browser is closed. I would like to use the same UID even if the page is refreshed. However, when I use the code below, a new UID and token is created every time a user refreshes the page. How do I prevent this from happening?
myApp.factory('fbAuth', function($firebaseAuth) {
var ref = new Firebase('https://xxxxxxxx.firebaseio.com');
ref.authAnonymously(function (error, authData) {
if (error) {
console.log('Login Failed!', error);
} else {
console.log('Authenticated successfully with payload:', authData);
}
},
{remember: 'sessionOnly'
});
});
myApp.controller('ProjectListCtrl', function(Projects, fbAuth) {
var projectList = this;
projectList.projects = Projects;
});

Angular rendering engine & Firebase profile retrieval

What I want:
firebase checks authentication of page load
firebase returns userID if logged in
my function returns the username associated with the user.Id
assign to the variable that represents the username
render!
All on page load
Current Behavior:
The following configuration retrieves the username but will only display the username once I click a login button I have made.For some reason even though I am currently logged in I must click the login button. I want a set up where if I am logged in the app will just know I am logged in from the start!
crossfitApp.controller('globalIdCtrl', ["$scope",'$q','defautProfileData','$timeout', function ($scope,$q,defautProfileData,$timeout) {
var dataRef = new Firebase("https://glowing-fire-5401.firebaseIO.com");
$scope.myFbvar =null;
$scope.authenticated={
currentUser: null,
avatarUrl: "",
emailAddress: "",
settings: "",
currentUserid: null,
};
function getProfile(userID,assignMe){
myprofile= new Firebase("https://glowing-fire-5401.firebaseio.com/profiles/"+userID+"/username");
myprofile.once('value', function(nameSnapshot) {
assignMe = nameSnapshot.val();
});
};
$scope.auth = new FirebaseSimpleLogin(dataRef, function(error, user) {
if (error) {
//Error
console.log ('error');
}
else if (user) {
//logged in
$timeout(function() {
getProfile(user.id,);
});
console.log('logged in');
$scope.authenticated.currentUserid = user.id ;
}
else {
// user is logged out
console.log('logged out');
$timeout(function() {
$scope.authenticated.currentUserid =null;
});
}
});
}]); //Global
In your else if( user ) logic, you forgot to put your scope var inside the $timeout, so it is being set properly, but Angular doesn't learn about it until the next time $apply is called (e.g. ng-click, ng-submit, etc).
Thus:
else if (user) {
//logged in
$timeout(function() {
getProfile(user.id,);
$scope.authenticated.currentUserid = user.id ; // moved into $timeout
});
console.log('logged in');
}
You can read more about why this matters here and here.

Resources