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.
Related
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";
});
I'm pretty new to developing in Ionic and I'm trying to integrate my application with Facebook login. I found this tutorial https://ionicthemes.com/tutorials/about/native-facebook-login-with-ionic-framework and I did everything the way it was shown but I'm getting the following error
TypeError: Cannot read property 'getLoginStatus' of undefined
at Scope.$scope.facebookSignIn (controllers.js:547)
at $parseFunctionCall (ionic.bundle.js:21172)
at ionic.bundle.js:53674
at Scope.$eval (ionic.bundle.js:23228)
at Scope.$apply (ionic.bundle.js:23327)
at HTMLAnchorElement.<anonymous> (ionic.bundle.js:53673)
at HTMLAnchorElement.eventHandler (ionic.bundle.js:11841)
at triggerMouseEvent (ionic.bundle.js:2865)
at tapClick (ionic.bundle.js:2854)
at HTMLDocument.tapTouchEnd (ionic.bundle.js:2977)
My Code for the controller is as follows:
.controller('WalkthroughCtrl', function($scope, $state, $q, UserService, $ionicLoading) {
var fbLoginSuccess = function(response) {
if (!response.authResponse){
fbLoginError("Cannot find the authResponse");
return;
}
var authResponse = response.authResponse;
getFacebookProfileInfo(authResponse)
.then(function(profileInfo) {
// For the purpose of this example I will store user data on local storage
UserService.setUser({
authResponse: authResponse,
userID: profileInfo.id,
name: profileInfo.name,
email: profileInfo.email,
picture : "http://graph.facebook.com/" + authResponse.userID + "/picture?type=large"
});
$ionicLoading.hide();
$state.go('app.feeds-categories');
}, function(fail){
// Fail get profile info
console.log('profile info fail', fail);
});
};
// This is the fail callback from the login method
var fbLoginError = function(error){
console.log('fbLoginError', error);
$ionicLoading.hide();
};
// This method is to get the user profile info from the facebook api
var getFacebookProfileInfo = function (authResponse) {
var info = $q.defer();
facebookConnectPlugin.api('/me?fields=email,name&access_token=' + authResponse.accessToken, null,
function (response) {
console.log(response);
info.resolve(response);
},
function (response) {
console.log(response);
info.reject(response);
}
);
return info.promise;
};
//This method is executed when the user press the "Login with facebook" button
$scope.facebookSignIn = function() {
facebookConnectPlugin.getLoginStatus(function(success){
if(success.status === 'connected'){
// The user is logged in and has authenticated your app, and response.authResponse supplies
// the user's ID, a valid access token, a signed request, and the time the access token
// and signed request each expire
console.log('getLoginStatus', success.status);
// Check if we have our user saved
var user = UserService.getUser('facebook');
if(!user.userID){
getFacebookProfileInfo(success.authResponse)
.then(function(profileInfo) {
// For the purpose of this example I will store user data on local storage
UserService.setUser({
authResponse: success.authResponse,
userID: profileInfo.id,
name: profileInfo.name,
email: profileInfo.email,
picture : "http://graph.facebook.com/" + success.authResponse.userID + "/picture?type=large"
});
$state.go('app.feeds-categories');
}, function(fail){
// Fail get profile info
console.log('profile info fail', fail);
});
}else{
$state.go('app.home');
}
} else {
// If (success.status === 'not_authorized') the user is logged in to Facebook,
// but has not authenticated your app
// Else the person is not logged into Facebook,
// so we're not sure if they are logged into this app or not.
console.log('getLoginStatus', success.status);
$ionicLoading.show({
template: 'Logging in...'
});
// Ask the permissions you need. You can learn more about
// FB permissions here: https://developers.facebook.com/docs/facebook-login/permissions/v2.4
facebookConnectPlugin.login(['email', 'public_profile'], fbLoginSuccess, fbLoginError);
}
});
};
})
Thank You in Advance.
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;
});
I got a service which first need to retrieve an accesstoken and then a User object. When this is done, further UI actions needs to be taken. The problem I have is that login().then() is invoked with a valid Session.accesstoken but a non-resolved promise for the Session.user. So I can't do any logic based on the user's info (e.g. role, etc.)
The following code I have:
In controllers.js (login() is invoked upon form credentials button click)
.controller('LoginController',
function($scope, SessionService) {
$scope.credentials = {
username : '',
password : ''
};
$scope.login =
function() {
SessionService.login($scope.credentials).then(function() {
console.info("succesfully logged in as user " + JSON.stringify(Session));
// further UI actions..
});
};
})
In services.js
.factory('SessionService',
function(User, Session, AuthorizationService) {
return {
login : function(credentials) {
return AuthorizationService.requestToken(credentials)
.then(function(token) {
console.info("Got token: " + token);
if (!!token) {
Session.create(token);
console.info("Fetching user...");
return User.get({
id : 'me'
});
} else {
throw (new Error("Could not log in"));
}
}).then(function(user) {
console.info("Got user: " + user);
if (!!user) {
Session.user = user;
} else {
throw (new Error("Could not fetch user"));
}
});
},
};
})
Here is the output of the console:
Got token: cf9c0eba82d872508f7dcc0b234f0d52 services.js:120
Fetching user...
services.js:124 Got user: [object Object]
services.js:132 succesfully logged in as user
{"token":"cf9c0eba82d772508f7dcc0b234f0d52","user":{"$promise":{},"$resolved":false}}
The User object is created by $resource and is not a promise; it is the actual object that will eventually be populated with the user info, but at this point of the code it contains nothing.
The solution is simple: from the first then do:
return User.get({...}).$promise;
The next then will be invoked with the user object as expected, but only when the data is actually fetched.
Per the documentation on the $logout method for $firebaseSimpleLogin, the API says clearly that
When logout is called, the $firebaseSimpleLogin:logout event will be fired, and the user >property on the object will be set to null.
However, it doesn't seem to work for me.
Here are snippets of my code:
var firebaseUrl = 'https://MYURL.firebaseio.com/';
var firebaseObject = new Firebase(firebaseUrl);
$rootScope.firebaseLoginObject = $firebaseSimpleLogin(firebaseObject, function(error, user) {
if (error) {
console.log(error);
} else if (user) {
console.log('User ID: ' + user.uid + ', Provider: ' + user.provider);
} else {
console.log('User is logged out');
// user is logged out
}
});
// Function for logging out.
$scope.logout = function() {
$rootScope.firebaseLoginObject.$logout();
console.log('i logged out successfully');
console.log($rootScope.firebaseLoginObject);
console.log($rootScope.firebaseLoginObject.user);
console.log($rootScope.user);
$location.path('/');
};
The output I get in the console after clicking "ng-click=logout()" shows that $rootScope.firebaseLoginObject is not set to null.
The problem is with $scope.logout. Your console.log statements are being executed before the $logout function has completed its work.
$scope.logout = function() {
$rootScope.firebaseLoginObject.$logout();
// This is not necessarily true. At this point, you may still be
// logged in since $logout can take an unknown amount of time to finish.
console.log('i logged out successfully');
console.log($rootScope.firebaseLoginObject);
console.log($rootScope.firebaseLoginObject.user);
console.log($rootScope.user);
$location.path('/');
};
To ensure you're logging the state of the firebaseLoginObject after $logout has finished, wait until the logout event has been broadcasted on $rootScope.
$rootScope.$on("$firebaseSimpleLogin:logout", function(event) {
// Log values here.
});