AngularFire (Angular + Firebase) Authentication Error delay - javascript

I found out something weird. Please help!
$scope.login = function() {
ref.authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(error, authData) {
if (error) {
console.log("Login Failed!", error);
$scope.message = error.toString();
} else {
$location.path('/meetings');
console.log("Authenticated successfully with payload:", authData);
}
});
} //login
This is a login function and it works nicely.However, the thing is that I get error 3, 4 sec after I have submitted the login. I noticed that my {{message}} is not being updated immediately after I receive value at $scope.message . I thought Angular should show that value as soon as it changes. ?
After I click for the second time, I get the error showed.
This is where I am printing the value:
<p class="error formerror" ng-show="message">{{message}}</p>

You're calling authWithPassword, which is part of Firebase's regular JavaScript SDK. This API will start the authentication process and call your function when the authentication completes. Unfortunately at that point AngularJS is no longer aware of any updates you make to $scope.
To make AngularJS aware of the update, wrap your code in a $timeout call:
$scope.login = function() {
ref.authWithPassword({
email: $scope.user.email,
password: $scope.user.password
}, function(error, authData) {
$timeout(function() {
if (error) {
console.log("Login Failed!", error);
$scope.message = error.toString();
} else {
$location.path('/meetings');
console.log("Authenticated successfully with payload:", authData);
}
});
});
} //login
Note that precisely for this reason, AngularFire provides convenience wrappers around these authentication functions in its $firebaseAuth service. See the section in the AngularFire guide on logging users in.
The wrapper function you're looking for is $authWithPassword, read a sample of how to use $authWithPassword in its API documentation.

Related

Problem handling Parse users in a web app

Here is some JS code, related to handling Parse users in a web app, with unexpected behaviour.
......
Parse.initialize(process.env.APP_ID);
Parse.serverURL = process.env.SERVER_URL;
Parse.User.logIn(req.body.usrname, req.body.password, {
success: user => {
console.log("OK-OK:"+user);
checkIfLoggedIn();
res.render('pages/index.ejs', {});
},
error: (user, error) => {
console.log("NG-NG:"+user, error);
checkIfLoggedIn();
res.render('pages/login.ejs', {});
},
});
......
function checkIfLoggedIn() {
var currentUser = Parse.User.current();
if (currentUser) {
console.log("Parse.User.current is A REAL USER -- logged in!!")
} else {
console.log("Parse.User.current is NULL -- login failed!!")
}
}
Now, below is the question.
When running the code above, the messages:
"OK-OK:" and "NG-NG:" both show up in the logs as expected. But the call to the function checkIfLoggedIn() always displays a failure:
Parse.User.current is NULL -- login failed!!
Why is that? Shouldn't it display a success when we reach "OK-OK:"?

AngularJS blocks login access to inactive users

I'am trying to block users with unactivated email tokens from accessing. Currently unactivated users can still log in and simply get an alert. This method uses the satellizer auth system, with a promise, then and a catch.
Here is my LoginCtrl
'use strict';
angular.module('myapp').controller('LoginCtrl', function ($scope, alert, auth, $state, $auth, $timeout) {
$scope.submit = function () {
$auth.login({
email: $scope.email,
password: $scope.password
})
.then(function(res) {
var message = 'Thanks for coming back ' + res.data.user.email + '!';
if (!res.data.user.active)
message = 'Just a reminder, please activate your account soon :)';
alert('success', 'Welcome', message);
return null;
})
.then(function() {
$timeout(function() {
$state.go('main');
});
})
.catch(handleError);
}
function handleError(err) {
alert('warning', 'oops there is a problem!', err.message);
}
});
I like to display an alert message "please activate first" at the same time block login. I appreciate your help. Basically, I want to check if the user is active, then login authorized, if not, login will not be possible.

How to handle error in Angular Controller from MongoDB database update/delete in Express?

I am trying to figure out how to handle an error when deleting or updating a document in MongoDB in Angular JS?
I have the following route in Node/Express:
function handleError(res, reason, message, code) {
console.log("ERROR: " + reason);
//log the reason for the error
res.status(code || 500).json({
"error": message
});
}
app.delete("/polls/:id", auth, function(req, res) {
db.collection(POLLS_COLLECTION).deleteOne({
_id: new ObjectID(req.params.id), userID: req.user.id
//userID must match the req.user.id from Passport to make sure the poll belongs to the user
}, function(err, doc) {
if (err) {
handleError(res, err.message, "Failed to delete poll");
} else {
res.status(204).end();
}
});
});
The following in an Angular JS controller:
$scope.deleteThisPoll = function(){
Polls.deletePoll($routeParams.pollId)
.then(function(response){
alert("Poll deleted!");
var url = "/mypolls/" + $scope.userID;
$location.path(url);
}, function(response){
alert("Error deleting poll");
console.log(response);
})
};
deleteThisPoll in the controller calls a deletePoll service that sends a a request to the route:
this.deletePoll = function(pollId){
var url = "/polls/" + pollId;
return $http.delete(url);
};
What I want is to alert "Error deleting poll" from the Angular controller when the database delete is not executed (because for example user is not authenticated or the poll doesnt belong to the user) and "Poll Deleted" when the delete was successfull.
However: the error callback is never used and the app always alerts "Poll deleted!" no matter if the document was deleted or not deleted.
Doesn't my route send an error response when the delete was not executed and will it not hit my Angular error callback?
You can do like code below
Put this HTML code where you want to show error message :
<div style="color:red;">
{{error}}
</div>
In your angular js controller :
$scope.deleteThisPoll = function(){
Polls.deletePoll($routeParams.pollId)
.then(function(response){
alert("Poll deleted!");
var url = "/mypolls/" + $scope.userID;
$location.path(url);
}, function(response){
$scope.error="Any error message you like to show";
console.log(response);
})
};
If your API return an error. you can catch it like this :
Polls.deletePoll($routeParams.pollId).then(function(response) {
//SUCCESS CODE
}).catch(function(error) {
//NOTIFY ERROR
//NotifyService.display(error);
console.log(error);
});
thanks guys. I found out that MongoDB for some reason always returns a result object even when there was no delete/update. I solved this by checking for the result.deletedCount propety that is set to 1 or 0. Like so:
if(err){
res.status(500).end();
}
if(result.deletedCount === 0){
res.status(404).end();
//error handling in Angular error callback
} else {
res.status(204).end();
//error handling in Angular success callback
}
});
});
this makes sure that not always a 204 is send whether or not the delete was successfull.

Can't get Facebook Login to work on Meteor

I cannot get Meteor.loginWithFacebook to work, I have looked at so many Q&A's here, and they all do it differently but none works for me. (It has only worked with accounts-ui, but I need my custom login page)
I have installed accounts-password, accounts-facebook and service-configuration
Server Code (Not Real ClientId or Secret):
ServiceConfiguration.configurations.upsert({
service: "facebook"
}, {
$set: {
clientId: "2234324234324",
loginStyle: "redirect",
secret: "324234234234324234234"
}
});
Client Code (on click button, using ui-router controller as variable "vm"):
vm.facebook = function() {
Meteor.loginWithFacebook({
requestPermissions: ['email']
},
function(err) {
if (err) {
return console.log("There was an error : " + err);
} else {
console.log('No Error!');
}
});
};

Meteor: Login over DDP and retrieve current user object in seperate Meteor app

First a little background:
I am working on an seperate mobile application that is connected with the main app. The connection is succesfully initiated and I can retrieve all collections, through subscriptions:
Remote = DDP.connect('http://localhost:3000/');
Meteor.users = new Meteor.Collection('users', {
connection: Remote
});
Remote.subscribe('users', true);
Now I want to make sure users can log in through the interface of the second app. After installing the accounts-password and the meteor-ddp-login package, I should be able to authenticate with the main app by using the next piece of code in the client side.
var Remote = DDP.connect('http://localhost:3000/');
DDP.loginWithPassword(Remote, {
username: username
}, password, function(error) {
if (!error) {
console.log(username + " is logged in!");
} else {
console.log(error);
}
});
Well, so far so good. No errors appear and the console logs a success message. Now the question comes:
How can I retrieve the user object of the user who just logged in.
I've set up several publish functions in the main app, but the user data does not become available to the client in the second app (other collections work fine, but Meteor.user() is undefined).
And also: How can I authenticate users who login with Facebook/Google/Twitter
Came across this, I had a similar need recently. Following code works in Meteor version 1.2.0.2
if (Meteor.isClient) {
Meteor.startup(function(){
//Seems that without this, on page refresh, it doesn't work.
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 1***********
var token = Accounts._storedLoginToken();
if(token) {
Meteor.loginWithToken(token, function(err){
// this is going to throw error if we logged out
if(err)
console.log(err);
else
console.log('loginWithToken');
});//loginWithToken
}
//hack block 1***********
});//startup function
var connection = DDP.connect("http://localhost:3060");
Accounts.connection= connection;
//COMMENT: Ideally this should not be needed if the core takes care of this use case of a different connection for Accounts
//hack block 2***********
Accounts.users = new Meteor.Collection('users', {
connection: connection
});
//hack block 2***********
Tracker.autorun(function () {
//No code which directly affects the functionality. Just for testing
console.log(Meteor.user());
Accounts.connection.call('user',function(err,result){
if(err)
console.log(err);
if(result){
console.log(result);
if(result._id === Meteor.user()._id){
console.log("Server and client shows that the same user has logged in");
} else {console.log("Server and client shows different users");}
}
})
});
Template.register.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#account-email').value
, password = t.find('#account-password').value;
Accounts.createUser({email:email,password:password}, function(err,result){
if (err) {
// Inform the user that account creation failed
console.log(err);
} else {
// Success. Account has been created and the user
// has logged in successfully.
console.log("registered user");
console.log('response is '+ result);
console.log(Meteor.user());
}
});//createUser
return false;
}
});//register
Template.login.events({
'submit #login-form': function(e,t){
e.preventDefault();
var email = t.find('#login-email').value
, password = t.find('#login-password').value;
Meteor.loginWithPassword(email, password, function(err){
if (err)
console.log(err);
else
// The user has been logged in.
console.log('logged in successfully');
});
return false;
}
});//login
Template.statusloggedin.events({
'click #logout': function(e,t){
e.preventDefault();
Meteor.logout();
return false;
}
});//logout
}

Categories

Resources