I am using Angular (1.3.5) and Firebase to write a toy blog program, and am currently struggling with the user login part.
I first created an Angular module:
var blogApp = angular.module('blogApp', ['ngRoute', 'firebase', 'RegistrationController']);
Then on top of blogApp, I created a controller called ** RegistrationController **:
blogApp.controller('RegistrationController', function ($scope, $firebaseAuth, $location) {
var ref = new Firebase('https://myAppName.firebaseio.com');
// var authLogin = $firebaseAuth(ref);
$scope.login = function(){
ref.authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(err, authData) {
if (err) {
$scope.message = 'login error';
} else {
$scope.message = 'login sucessful!';
}
});
}; // login
}); //RegistrationController
I attached the login() method to ng-submit in my user-login form in the scope of RegistratinController.
When I click to submit the login form, the form does not make any response, without any errors showing.
The login form works only when I click the 'Submit' button twice - why is this? confusing
You are using the Firebase JavaScript library and not AngularFire for the login methods.
You need to pass the Firebase reference into the $firebaseAuth binding.
var auth = $firebaseAuth(ref);
From there you can call auth.$authWithPassword.
$scope.login = function(){
auth.$authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(err, authData) {
if (err) {
$scope.message = 'login error';
} else {
$scope.message = 'login successful!';
}
});
}; // login
AngularFire is an Angular binding for the Firebase Library that handles auto syncing over objects and arrays. AngularFire also handles when to call $scope.apply to properly update the view.
In your case, the login code is working the first click, but it doesn't get applied to the page. You can wrap this code in a $timeout, but it would be better to use the $firebaseAuth service.
Thanks to user jacobawenger, for the solution he posted here:
Can't get new password authentication methods to work in AngularFire 0.9.0?
This works as expected:
myApp.controller('RegistrationController',
function($scope, $firebaseAuth, $location) {
var ref = new Firebase('https://myApp.firebaseio.com');
var simpleLogin = $firebaseAuth(ref);
$scope.login = function() {
simpleLogin.$authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}).then(function() {
$location.path('/mypage');
}, function(err) {
$scope.message = err.toString();
});
} // login
}); // RegistrationController
Related
I'm trying to implement the facebook login in my angular application. the login works alright but the issue is after the login i want to alert the data that is coming from facebook but I'm having problems with it.
.controller('facebook_login',['$scope', '$ionicModal', '$timeout', 'ngFB', function($scope, $ionicModal, $timeout, ngFB) {
$scope.fbLogin = function () {
ngFB.login({scope: 'email,public_profile,publish_actions'}).then(
function (response) {
if (response.status === 'connected') {
//alert('Facebook login succeeded, got access token: ' + response.authResponse.accessToken);
//$scope.closeLogin();
ngFB.api({
path: '/me',
params: {fields: 'id,name'}
}).then(
function (user) {
$scope.user = user;
alert(params)
});
} else {
alert('Facebook login failed');
}
});
};
}])
Please try changing the params: fields to the following
fields: 'first_name,last_name,gender,email,picture'
Instead of invoking alert on the params, alert on the response object i.e. user in this case.
alert(user)
I am running a ionic project and I visualize it live with the Ionic Lab tool. It is pretty good because each time I modify a html doc, it shows live what's going on.
Now, I have inserted a controller at the bottom of my controllers.js and it just breaks my project. What I mean by that is that if I take the code off of the controllers.js file, the project shows up normally but if I put it, it justs make the entire project go blank. Like if nothing was on it.
Here is the code I added :
.controller('AccountCtrl', function($scope, $state, $cordovaOauth) {
$scope.$on('$ionicView.enter', function() {
//Authentication details.
JSON.stringify(firebase.auth().currentUser));
//Get logged in user credentials.
var user = firebase.auth().currentUser;
var name, email, photoUrl, provider;
if (user != null) {
name = user.displayName;
email = user.email;
photoUrl = user.photoURL;
provider = user.provider;
}
//Set Profile Image.
profileImage = photoUrl;
//Set Profile Name.
profileName = name;
//It is now up to you to set provider and email!
})
});
And here is my complete document :
angular.module('starter.controllers', [])
.controller('LoginCtrl', function($scope, $state, $cordovaOauth) {
$scope.signIn = function() {
$state.go('tab.dash');
};
$scope.facebook = function() {
var facebookAppId = "198040820571843";
$cordovaOauth.facebook(facebookAppId, ["public_profile", "email"]).then(function(response) {
var credential = firebase.auth.FacebookAuthProvider.credential(response.access_token);
loginWithCredential(credential, 'Facebook');
}, function(error) {
//User cancelled login. Hide the loading modal.
});
}
$scope.twitter = function() {
var twitterKey = "aJWByCgPhUgYZJMojyFeH2h8F";
var twitterSecret = "XxqKHi6Bq3MHWESBLm0an5ndLxPYQ2uzLtIDy6f9vgKKc9kemI";
$cordovaOauth.twitter(twitterKey, twitterSecret).then(function(response) {
var credential = firebase.auth.TwitterAuthProvider.credential(response.oauth_token,
response.oauth_token_secret);
loginWithCredential(credential, 'Twitter');
}, function(error) {
//User cancelled login. Hide the loading modal.
});
};
loginWithCredential = function(credential, provider) {
firebase.auth().signInWithCredential(credential)
.then(function(response) {
//User logged in through provider.
$state.go('tab.dash');
})
.catch(function(error) {
//Show error message.
var errorCode = error.code;
});
};
});
.controller('AccountCtrl', function($scope, $state, $cordovaOauth) {
$scope.$on('$ionicView.enter', function() {
//Authentication details.
JSON.stringify(firebase.auth().currentUser));
//Get logged in user credentials.
var user = firebase.auth().currentUser;
var name, email, photoUrl, provider;
if (user != null) {
name = user.displayName;
email = user.email;
photoUrl = user.photoURL;
provider = user.provider;
}
//Set Profile Image.
profileImage = photoUrl;
//Set Profile Name.
profileName = name;
//It is now up to you to set provider and email!
})
});
I really don't understand what is going on, it just breaks everything !
And I call that controller in the app.js :
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html'
}
},
controller: 'AccountCtrl'
})
If anybody has any help... Thanks !
EDIT , in the console, here is the error :
?ionicplatform=android:29 Uncaught SyntaxError: Unexpected token . http://localhost:8100/js/controllers.js Line: 43console.(anonymous function) # ?ionicplatform=android:29
controllers.js:43 Uncaught SyntaxError: Unexpected token .
It is the line that starts my controller of course...
Two issues:
You have a trailing semicolon (;) on the controller LoginCtrl.
Your AcctCtrl cannot be fluently attached to your angular module because of that trailing semicolon on the controller above it.
Second,
This line has one too many closing )
JSON.stringify(firebase.auth().currentUser));
It should be:
JSON.stringify(firebase.auth().currentUser);
From line:41 remove the simi-colon, this breaks the chain of reference to angular.
I´m working on an android game using ionic framework and firebase.
My plan is to let users login using facebook login with firebase, after this i want to save the game data to the users database key.
The first part is working. the script makes an database array based on the users facebook details. but the problem is after this is made, i cant seem to let angular change any database data. It seems like the authData is stuck in the login function...
Is there a way to keep the authdata for use in different controllers and functions?
app.factory("Auth", function($firebaseAuth) {
var FIREB = new Firebase("https://name.firebaseio.com");
return $firebaseAuth(FIREB);
});
app.controller('HomeScreen', function($scope, Auth, $firebaseArray) {
Auth.$onAuth(function(authData){
$scope.authData = authData;
});
var users = new Firebase("https://name.firebaseio.com/users/");
// create a synchronized array
$scope.users = $firebaseArray(users);
$scope.facebooklogin = function() {
Auth.$authWithOAuthPopup("facebook").then(function(authData){
users.child(authData.facebook.cachedUserProfile.id).set({
Username: authData.facebook.displayName,
Id: authData.facebook.cachedUserProfile.id,
Gender: authData.facebook.cachedUserProfile.gender,
Email: authData.facebook.email,
level: "1"
});
}).catch(function(error){
});
}
$scope.facebooklogout = function() {
Auth.$unauth();
}
$scope.changeLVL = function(authData) {
users.child(authData.facebook.cachedUserProfile.id).set({
level: "2"
});
}
});
And this is the datastructure it creates in firebase
users
998995300163718
Email: "Name#email.com"
Gender: "male"
Id: "998995300163718"
Username: "name lastname"
level: "1"
and after trying to edit i get this error... (using the changelevel function)
TypeError: Cannot read property 'facebook' of undefined
at Scope.$scope.changeLVL (http://localhost:8100/js/controllers.js:35:23)
at fn (eval at <anonymous> (http://localhost:8100/lib/ionic/js/ionic.bundle.js:21977:15), <anonymous>:4:218)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:57606:9
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:24678:28)
at Scope.$apply (http://localhost:8100/lib/ionic/js/ionic.bundle.js:24777:23)
at HTMLButtonElement.<anonymous> (http://localhost:8100/lib/ionic/js/ionic.bundle.js:57605:13)
at HTMLButtonElement.eventHandler (http://localhost:8100/lib/ionic/js/ionic.bundle.js:12103:21)
at triggerMouseEvent (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2870:7)
at tapClick (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2859:3)
at HTMLDocument.tapMouseUp (http://localhost:8100/lib/ionic/js/ionic.bundle.js:2932:5)
The main issue is you're relying on the cachedUserProfile.gender property to exist. This isn't guaranteed to be there for every user. You'll need to find a fallback to avoid an error.
Let's simplify by injecting the user via the resolve() method in the router. Don't mind the structure of the code, it's from the Angular Styleguide (my preferred way of writing Angular apps).
angular.module("app", ["firebase"])
.config(ApplicationConfig)
.factory("Auth", Auth)
.controller("HomeScreen", HomeController);
function Auth() {
var FIREB = new Firebase("https://name.firebaseio.com");
return $firebaseAuth(FIREB);
}
function ApplicationConfig($stateProvider) {
$stateProvider
.state("home", {
controller: "HomeScreen",
templateUrl: "views/home.html"
})
.state("profile", {
controller: "ProfileScreen",
templateUrl: "views/profile.html",
resolve: {
currentUser: function(Auth) {
// This will inject the authenticated user into the controller
return Auth.$waitForAuth();
}
}
});
}
function HomeController($scope, Auth, $state) {
$scope.googlelogin = function() {
Auth.$authWithOAuthPopup("google").then(function(authData) {
users.child($scope.authData.google.cachedUserProfile.id).set({
Username: $scope.authData.google.cachedUserProfile.id,
Gender: $scope.authData.google.cachedUserProfile.gender || ""
});
$state.go("app.next");
});
}
}
function ProfileController(currentUser) {
console.log(currentUser.facebook); // injected from router
}
The benefit of this approach is that you don't have to check for authenticated users in the controller. If the user is injected, you know you have an authenticated user.
Check out the AngularFire docs for more information.
I have the following code. I am using ng-show on html and try to manipulate it on the angular function but it did not work. I am not sure about the correct way to change a $scope value inside a function.
On Angular,
app.controller("ControlController", function($scope, $http, $location) {
$scope.badRequest = false;
$scope.login = function() {
$http.post('/login', {
email: $scope.email,
password: $scope.password
}).then function(res) {
$location.path('/');
},function(err) {
$scope.badRequest = true;
console.log($scope.badRequest); // this will print true.
//But this does not change the $scope.badRequest on DOM.
});
};
});
On Jade, I have
.incorrect-container(ng-show='badRequest')
Any help?
Not sure if it's just that you copied it over wrong, but ".then" is a function call. it should be
$scope.login = function() {
$http.post('/login', {
email: $scope.email,
password: $scope.password
})
.then(function(data) {
// do stuff in here with successfully returned data
})
.catch(function(err) {
$scope.badRequest = true;
});
};
The way you have it, .then is not even being called. Also, when I ran it as it was, I got syntax errors. are you not getting those?
Tutorial: http://www.thinkster.io/angularjs/wBhtRLWHIR/6-authenticating-users-with-a-service
I'm following this tutorial and it seems like I'm losing my user as soon as they register.
Here is my auth.js factory:
'use strict';
app.factory('Auth', function($firebaseSimpleLogin, FIREBASE_URL, $rootScope){
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseSimpleLogin(ref);
var Auth = {
register : function(user) {
return auth.$createUser(user.email, user.password);
},
signedIn : function() {
// PROBLEM: authUser is always null
console.log(auth.user);
return auth.user !== null;
},
logout : function () {
auth.$logout();
}
};
$rootScope.signedIn = function () {
return Auth.signedIn();
};
return Auth;
});
Here is my auth.js controller:
'use strict';
app.controller('AuthCtrl', function($scope, $location, Auth){
if (Auth.signedIn()) {
$location.path('/');
}
$scope.register = function () {
Auth.register($scope.user).then(function (authUser) {
console.log(authUser);
$location.path('/');
});
};
});
The console.log under signedIn in the factory is always null. Any idea where the disconnect is? The registration itself is working fine, and authUser is populated in the console.log in the controller when registering.
The latest documentation for Angularfire says that the $createUser method of $firebaseSimpleLogin returns a promise but it doesn't mention any parameters being passed to the then callback.
You can use the $getCurrentUser method to get the current user after the user registers.
The tutorial needs to be updated and you should always be checking the documentation for whatever libraries you're using yourself.
Your code for signedIn should look like this:
Auth.signedIn = function() {
auth.$getCurrentUser().then(function(currentUser) {
console.log(currentUser);
}, function() {
console.log('error');
});
};
I found a very similar question that is further along in the tutorial :can't show logout button after $createUser
In the answer I learned that angularfire used to automatically log the user in after it was created. Apparently now it no longer does that which is why the auth.user in signedIn was null.
I am now doing the same tutorial. This code (in auth controller) worked for me:
$scope.register = function () {
Auth.register($scope.user).then(function (authUser) {
console.log(authUser);
Auth.login($scope.user);
$location.path('/');
});
};
I'm a total n00b, but what (I think) this is doing is authenticating the user, then running a function that logs the user in right after. Logout button is now functioning as expected.