Firebase createUser() does not return id of created user - angularjs

I'm using Firebase 1.1 (which embeds old firebase-simple-login functionalities).
Now, when creating a user, how do I get it's id (or uid)?
app.controller('AuthCtrl', function ($scope, $firebase) {
var ref = new Firebase(MY_FIREBASE_URL);
ref.createUser({
email: 'mary#mail.com',
password: 'her-super-secret-password'
},
function(err) {
switch (err.code) {
...
}
}
}
As far as I can understand, createUser function callback only reports an err object in case of error. But - in case of success - I need the created user id (or better uid), to use it to add the user to my internal users profiles...
How do I get created user id from Firebase createUser ?
UPDATE:
I did just give up with 1.1, reverting to 1.0 until some more docs are available (or some answer I get...) :-(

Firebase recently released an updated JavaScript client (v2.0.5) which directly exposes the user id of the newly-created user via the second argument to the completion callback.
Check out the changelog at https://www.firebase.com/docs/web/changelog.html and see below for an example:
ref.createUser({
email: '...',
password: '...'
}, function(err, user) {
if (!err) {
console.log('User created with id', user.uid);
}
});

Related

Reactjs AWS Cognito - How to Handle newPasswordRequired

I'm using AWS Cognito Javascript SDK in a react application. I have a user that was created in the AWS Console by an admin. The user recieves an email with their username and temporary password. Now based on my understanding, I have to go through the newPasswordRequired flow, but I have been struggling with this for several hours now trying multiple different approaches and none are getting me anywhere. When I check the AWS Console, the user in the user pool is set to FORCE_CHANGE_PASSWORD.
Here is my code in its current state. Please if someone can help me solve the process as I am fairly new to using Cognito authentication.
function setNewPassword(data) {
console.log("data \n", data)
var authenticationData = {
Username: data.username,
Password: data.temp_password
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
authenticationData
);
var userPool = new AmazonCognitoIdentity.CognitoUserPool(config.cognito);
var userData = {
Username: data.username,
Pool: userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
return new Promise(function(resolve, reject) {
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function(result) {
resolve(resolve);
},
onFailure: function(err) {
reject(err);
},
newPasswordRequired: function(userAttributes, requiredAttributes) {
this.cognitoUser.completeNewPasswordChallenge(newPassword, attributesData, this)
}
});
});
}
In the browser console, I am getting the following error:
{code: "UnknownError", message: "Unkown error"}
Have you looked at using the AWS Amplify JS library for help here? There's a suite of React components already built to help with these sorts of things. Here's a link to the relevant documentation. The code is open sourced on GitHub and you might be able to just use the RequireNewPassword component, or at least find inspiration from it.

Network error when authenticating user with AWS Cognito

I'm trying to incorporate Cognito authentication into my React based project. My code is based on examples given in NPM page. This is what it looks like :
var authenticationData = {
Username : 'username',
Password : 'password',
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
UserPoolId : '...', // Your user pool id here
ClientId : '...' // Your client id here
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
Username : 'username',
Pool : userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
console.log('Successfully logged!');
}
});
},
onFailure: function(err) {
console.log(JSON.stringify(err));
},
});
I have created a user pool and added an app client. I have also enabled identity provider for app client. However, my code fails to authenticate with error {"code":"NetworkError","name":"Error","message":"Network error"}. Since my project is still hosted on a localhost, I have installed CORS plug-in for firefox, but that doesn't resolve the issue. I couldn't make much sense out of this error message. I have double checked Cognito region, pool id and client id. They all set to correct values. Does anyone familiar with this error and have an idea what maybe causing this?
A bit late, but I had exactly the same error today and it took me a while to figure it out. This happens when the automatic refresh occurs after a submit. This prevents the API call to AWS Cognito to finish resulting in a network error.
Before starting the cognito function, add a event.preventDefault(); to your code.
For example, I do this in my addEventListener:
document.querySelector("#authCognito").addEventListener("click", function(){
var username = document.getElementById("userInput").value;
var password = document.getElementById("passInput").value;
var authenticationData = {
Username: username,
Password: password,
};
event.preventDefault();
cognitoAuthenticate(authenticationData);
});
I had the same issue, the following is the fix in Vue
<template>
<button v-on:click="login($event)" class="btn btn-default btn-large">login</button>
</template>
<script>
methods: {
login (event) {
if (event) {
event.preventDefault()
}

How to save the google login as an app user?

So I have some code that authenticates the user to my app using google which works out fine. What I want to do is then save that user info to the firebase and then have that user be able add data specifically under their account that will then reload the next time they log in. What's the best way to do that? I'm getting very lost.
(function() {
'use strict';
angular.module('life-of-a-story')
.controller('UserController', function($scope, $firebaseAuth) {
var ref = new Firebase('https://life-of-a-story.firebaseio.com/');
// create an instance of the authentication service
var auth = $firebaseAuth(ref);
// login with Google
this.login = function() {
auth.$authWithOAuthPopup("google").then(function(authData) {
console.log(authData);
console.log("Logged in as:", authData.uid);
var user = {
'name': authData.google.displayName,
'image': authData.google.profileImageURL,
'uid': authData.uid
}
console.log(user);
}).catch(function(error) {
console.log("Authentication failed:", error);
});
};
});
})();
AngularFire is a (relatively) thin UI binding library on top of Firebase's regular JavaScript SDK. So when something is not explicitly documented in the AngularFire documentation, you can sometimes find the answer in the documentation for the regular Firebase JavaScript SDK.
Most Firebase Authentication developers store each user's data under a /users node. If that is what you're trying to do, you can read how to accomplish it in the section called Storing user data in the Firebase documentation for JavaScript.
The relevant code from there:
// we would probably save a profile when we register new users on our site
// we could also read the profile to see if it's null
// here we will just simulate this with an isNewUser boolean
var isNewUser = true;
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(function(authData) {
if (authData && isNewUser) {
// save the user's profile into the database so we can list users,
// use them in Security and Firebase Rules, and show profiles
ref.child("users").child(authData.uid).set({
provider: authData.provider,
name: getName(authData)
});
}
});
// find a suitable name based on the meta info given by each provider
function getName(authData) {
switch(authData.provider) {
case 'password':
return authData.password.email.replace(/#.*/, '');
case 'twitter':
return authData.twitter.displayName;
case 'facebook':
return authData.facebook.displayName;
}
}

How to secure feature for authenticated users only in Meanjs when using angularjs

I am working on my first app, and have started with the front-end and angularjs. In general I have found it very intuitive, but the relationship between backend and frontend is where things start to blur for me.
I have now gotten to the point where I want to provide slightly different functionality on some pages depending on whether the user is authenticated or not (in this case the ability to edit some form fields in a form).
From the public angularjs side it seems easy enough to write a basic if statement to provide different functionality to authenticated users (see basic attempt below) but as this is a client side function, how do I prevent a user spoofing authentication to edit things I don't want them to (save to database).
angular.module('core').controller('myCtrl', ['$scope', 'Authentication', 'Menus',
function($scope, Authentication, Menus) {
$scope.authentication = Authentication;
if(typeof $scope.authentication.user == "object"){
// behaviour for authenticated
}else{
// for unauthenticated
}
}
I am new to mean, meanjs and node.js in general, being primarily a php guy, so please be gentle if my question is way off base.
I suggest using passport a npm module for user authentication. Here's some code to get you started. Also take a look at this scotch.io tutorial
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../app/models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error before anything else
if (err)
return done(err);
// if the user is found but the password is wrong
if (!user || !user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong username or password.')); // create the loginMessage and save it to session as flashdata
// all is well, return successful user
return done(null, user);
});
}));
};

passportjs and passportlocal add users "Error: failed to serialize user into session"

I have followed the code here - > https://github.com/jaredhanson/passport-local/tree/master/examples/express3 for add local authentication for users.
The problem is when I try to add users,
So I created this route
app.get('/signup', function(req,res){
res.render('/signup');
});
app.post('/signup', function(req,res){
var body = req.body;
users.push(body);
res.redirect('/');
});
Then the page w the form It's
form(method='POST', action='/signup')
input(type='text', name='username', placeholder='username')
input(type='text', name='password', placeholder='password')
button.btn Register
The dummy DB It's the one on the example
users = [
{id:1, username: 'test', password:'papapa'}
];
So when I send the info w the form, all goes ok, but when I try to log in with the new created user, tells me "Error: failed to serialize user into session"
the serializeUser is this
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
findById(id, function (err, user) {
done(err, user);
});
});
The user being pushed in the POST /signup route will not have an ID, which the examples serialization code expects.
Change it to something like this, and it should work.
app.post('/signup', function(req,res){
var body = req.body;
body.id = users.length;
users.push(body);
res.redirect('/');
});
(Note that this is an example only, and not recommended for "real" apps.)
I guess you are missing the session serializer. Take a look to https://github.com/jaredhanson/passport, section 'Sessions'.
Basically, you need two functions, to save the current user into the session (passport.serializeUser) and to read it back (passport.deserializeUser).

Resources