I'm running this code in my react app:
componentDidMount() {
modelInstance.addObserver(this);
modelInstance.getSignInStatus().then((user)=>{
this.setState({
userName: user !== false ? user.displayName : "Sign in",
logged_in: user !== false ? true : false
});
});
}
And here is modelInstance.getSignInStatus():
this.getSignInStatus = function () {
return new Promise((resolve, reject)=>{
firebase.auth().onAuthStateChanged(function(user){
if (user){
resolve(user);
}
else {
resolve(false);
}
});
});
}
What happens is that this.state.userName is set to null, meaning that user.displayName is null. Why is this?
state = {
username: "",
email: "",
passwordOne: "",
passwordTwo: "",
error: null
};
onSubmit = event => {
const {username, email, passwordOne} = this.state;
const {history} = this.props;
auth
.createUserWithEmailAndPassword(email, password);
.then(authUser => {
db.doCreateUser(authUser.uid, username, email).then(() => {
//you should clear your state fields here, for username / email etc
console.log(authUser);
//redirect user
history.push(routes.HOME);
});
})
.catch(error => {
this.setState({error});
});
event.preventDefault();
};
const auth = firebase.auth();
const db = firebase.database();
in order to acess doCreateUser
const doCreateUser = (id, username, email) =>
db.ref(`users/${id}`).set({
uid:id,
username,
email,
});
I would use setState for checking the auth status like so:
firebase.auth().onAuthStateChanged(function(user){
if (user){
this.setState({user});
}
}
Then you want the state of the displayName of the current user
componentDidMount() {
modelInstance.addObserver(this);
modelInstance.getSignInStatus().then((user)=>{
this.setState({
userName: this.state.user ? this.state.user.displayName : "Sign in",
logged_in: this.state.user ? true : false
});
});
}
Obviously there has to be a name in the displayName property, If not you would have to update it. Let me know how this turns out.
Related
I'd like to update the user's data in Firestore whenever they log in and am using the following code to do so. For some reason, the code doesn't work (see comments) and doesn't create a custom User object from firebase.User. Why is this happening/how do I fix this? I'm not getting any errors.
Code that is called to log in
async emailLogIn(email: string, password: string) {
return this.auth.signInWithEmailAndPassword(email, password)
.then( async (credential) => {
this.analytics.logEvent('logged_in', { method: 'email' });
const firebaseUser = credential.user;
if(firebaseUser) {
const user = await this.createUserFromFirebaseUser(firebaseUser);
console.log(user); // This doesn't print anything
this.updateUserData(user);
if(!firebaseUser.emailVerified) {
this.sendEmailVerification();
}
}
});
}
Code that is convert firebase.User to User (doesn't work)
async createUserFromFirebaseUser(firebaseUser: firebase.User): Promise<User> {
console.log('createUserFromFirebaseUser()');
const currentUser = await this.user.toPromise();
console.log(currentUser); // This doesn't print anything
if(currentUser)
return currentUser;
const user: User = {
uid: firebaseUser.uid,
email: firebaseUser.email,
displayName: firebaseUser.displayName,
settings: {
language: 'English',
isPrivate: false,
newFountainNotification: true,
userFountainNotification: true,
feedbackNotification: true,
units: 'Metric'
}
}
return user;
}
Getting user data from Firestore
this.user = this.auth.authState.pipe(
takeUntil(this.destroy),
switchMap( (user) => {
if(user) {
return (this.firestore.collection('users').doc(user.uid).valueChanges() as Observable<User>)
} else {
return of(null);
}
})
);
It seemed to be an issue with using this.user.toPromise()
This is the code that works:
return this.user.pipe(
take(1),
map( (currentUser) => {
if(currentUser)
return currentUser;
const user: User = {
uid: firebaseUser.uid,
email: firebaseUser.email,
displayName: firebaseUser.displayName,
settings: {
language: 'English',
isPrivate: false,
newFountainNotification: true,
userFountainNotification: true,
feedbackNotification: true,
units: 'Metric'
}
}
return user;
})
).toPromise()
y'all, I'm trying to create a signup and login local-Strategy with passport and have been seeing a PROXY ERROR:. I thought I was returning all possible endings for the functions but maybe I'm missing something? I'm new to development and am going crazy haha... Any help is much appreciated, also let me know if I missed adding pertinent code. (I did not add the return block from the react component, I assumed it unnecessary). I am importing my strategies through a strategy index.js (also did not include).
SignupStratagy.js / local strategy
const Strategy = require("passport-local").Strategy;
const User = require("../models/User");
// for password encryption;
const bcrypt = require("bcrypt");
const saltRounds = 10;
const SignupStrategy = new Strategy({ passReqToCallback: true }, function (
req,
username,
password,
done
) {
// console.log(username, password);
const encryptedPass = bcrypt.hashSync(password, saltRounds);
// console.log("encryptedPassword", encryptedPass);
const phone = req.body.phone;
const email = req.body.email;
const street = req.body.street;
const city = req.body.city;
const state = req.body.state;
const zip = req.body.zip;
const isAdmin = req.body.isAdmin;
User.findOne({ username: username }, (err, user) => {
// console.log("SignupStrategy.js / req:", req.body);
if (err) {
return done(err, user);
}
if (user) {
return done("User Name is already taken:", user);
}
})
// .lean()
// .exec();
// console.log("SignupStrategy.js / encrypted password:", encryptedPass);
let newUser = {
username,
password: encryptedPass,
phone,
email,
street,
city,
state,
zip,
isAdmin,
};
User.create(newUser, (error, newUser) => {
if (error) {
return done(error, null);
}
// delete the user password before it is sent back to the front-end;
newUser.password = undefined;
delete newUser.password;
return done(null, newUser);
});
});
module.exports = SignupStrategy;
apiRoute.js / route for signup
const router = require("express").Router();
const db = require("../models");
const passport = require("../config");
// const isAuthenticated = require("../config/middleware/isAuthenticated");
// USER SIGN-UP ROUTE
router.post("/api/signup", function (req, res, next) {
// console.log(req.body);
passport.authenticate("local-signup", (error, user) => {
// console.log("apiRoutes.js / error:", error, "apiRoutes.js / user:", user)
if (error)
return res.status(500).json({
message: error,
});
else {
return res.status(200).json(user);
}
})(req, res, next);
});
Signup / react component
import React, { useState } from "react";
import axios from "axios";
import { Redirect, Link } from "react-router-dom";
import chip from "../../images/chipper/chipperOne.png";
import "./style.css";
function Signup() {
const [signupState, setSignupState] = useState({
username: "",
password: "",
phone: "",
email: "",
street: "",
city: "",
state: "",
zip: "",
key: "",
redirect: false,
adminRedirect: false,
isAdmin: false,
});
const onChange = (e) => {
// console.log("working")
// console.log(typeof e.target.type)
if (e.target.type === "checkbox") {
if (signupState.isAdmin === false) {
setSignupState({
...signupState,
isAdmin: true,
})
} else {
setSignupState({
...signupState,
isAdmin: false,
});
}
} else {
setSignupState({
...signupState,
[e.target.name]: e.target.value,
});
}
};
const onSubmit = async (e) => {
e.preventDefault();
if (signupState.isAdmin === true) {
const response = await axios.post("/api/admin-sign-up", {
key: signupState.key,
});
console.log(response.status);
if (response.status === 500) {
console.log(response);
return;
}
if (response.status === 200) {
console.log(response.status);
setSignupState({
...signupState,
adminRedirect: true,
});
}
}
// console.log(`onSubmit ${signupState}`);
axios.post("/api/signup", {
username: signupState.username,
password: signupState.password,
phone: signupState.phone,
email: signupState.email,
street: signupState.street,
city: signupState.city,
state: signupState.state,
zip: signupState.zip,
isAdmin: signupState.isAdmin,
})
.then((res) => {
console.log(res);
if (res.data) {
console.log(`Sign-in Successful`);
setSignupState({
...signupState,
redirect: true,
});
}
})
.catch((err) => {
if (err) console.log(`Sign-Up server error ${err}`);
});
};
ERROR:
Proxy error: Could not proxy request /api/signup from localhost:3000 to http://localhost:3001.
[1] See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
For, an user verification now I hardcoded the username and password directly on my code. But I want this dynamically using database username and password. As, i'm new to hapi.js it seems quite difficult for me. This is my code :
app.js
const auth = require('hapi-auth-basic');
const hapi = require('hapi');
mongoose.connect('mongodb://localhost:27017/db', {
useNewUrlParser: true }, (err) => {
if (!err) { console.log('Succeeded.') }
else { console.log(`Error`)}
});
const StudentModel = mongoose.model('Student', {
username: String,
password: String
});
const user = {
name: 'jon',
password: '123'
};
const validate = async (request, username, password, h) => {
let isValid = username === user.name && password === user.password;
return {
isValid: isValid,
credentials: {
name: user.name
}
};
};
const init = async () => {
await server.register(auth);
server.auth.strategy('simple', 'basic', {validate});
server.auth.default('simple');
server.route({
method: 'GET',
path: '/',
handler: async (request, h) => {
return 'welcome';
}
});
}
I tried to do this by changing the validate as below :
const validate = async (request, username, password, h) => {
let isValid = username === request.payload.name && password === request.payload.password;
return {
isValid: isValid,
credentials: {
name: request.payload.name
}
};
};
but i got the type error "name" as it's natural. How can I modify this?
Here, fetch user and check in the validation method
const validate = async (request, username, password, h) => {
// fetch user here
const user = await StudentModel.findOne({username, password}).exec();
// user doesn't exist
if(!user) return {isValid: false}
// just make sure here user really exists
return {
isValid: true,
credentials: {
name: user.name
}
}
}
I build some authentication app including input username, password on firebase. But nothing happen after i press on Log in button on my application. It only shows "Authentication Failed".
class LoginForm extends Component {
state = {
email: '',password: '',error: '',loading: false
};
onButtonPress() {
const { email, password } = this.state;
this.setState({ error: '', loading: true });
firebase.auth().signInWithEmailAndPassword(email, password)
.then(this.onLoginSuccess.bind(this))
.catch(() => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(this.onLoginSuccess.bind(this))
.catch(this.onLoginFail.bind(this));
});
}
onLoginFail() {
this.setState({ error: 'Authentication Failed.', loading: false });
}
onLoginSuccess() {
this.setState({
email: '',password: '',error: '',loading: false});
}
render
....
value={this.state.email}
onChangeText={email => this.setState({ email })}
/>
</CardSection>
<CardSection>
<Input
...
onChangeText={password => this.setState({ password })}
/>
Try to catch the error and console.log it.
onButtonPress() {
const { email, password } = this.state;
this.setState({ error: '', loading: true });
firebase.auth().signInWithEmailAndPassword(email, password)
.then(this.onLoginSuccess.bind(this))
.catch((error) => { <===
console.log(error); <===
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(this.onLoginSuccess.bind(this))
.catch(this.onLoginFail.bind(this));
});
}
I can not quite understand how do users with different rights, here are the rules:
{"rules":
{"authentication":
{"users":
{"$uid": {
".read": "auth.uid == $uid || root.child('authentication').child('users').child('auth.uid').child('isAdmin').val() == true",
".write": "newData.parent().parent().parent().child('authentication').child('users').child('auth.uid').child('isAdmin').val() == true",
".indexOn": [
"email"
]
}
}
}
}
}
user: link screen user
Realtime Database:
{
"users" : {
"-KVVe4Ncd5Qnm5r37zVp" : {
"email" : "admin#gmail.com",
"isAdmin" : true,
"name" : "admin"
},
"-KVVeADyh07mBXBFImtq" : {
"email" : "djvang92#gmail.com",
"isAdmin" : true,
"name" : "Ivan"
}
}
}
Firebase script:
// Initialize Firebase
const config = {
apiKey: "AIzaSyAfeEpMopsPWnowiv1uEWYINgk6V_ohvG4",
authDomain: "spalah-1358.firebaseapp.com",
databaseURL: "https://spalah-1358.firebaseio.com",
storageBucket: "spalah-1358.appspot.com",
messagingSenderId: "300000265085"
}
firebase.initializeApp(config)
export const db = firebase.database();
export const auth = firebase.auth()
console.log(auth);
// var provider = new firebase.auth.GoogleAuthProvider();
// var provider = new firebase.auth.FacebookAuthProvider();
// var provider = new firebase.auth.TwitterAuthProvider();
// var provider = new firebase.auth.GithubAuthProvider();
export default {
// User object will let us check authentication status
user: {
authenticated: false,
data: null,
message: ''
},
login(context, creds, redirect) {
console.log('Login...');
let self = this;
let email = creds.email;
let password = creds.password;
let promise = auth.signInWithEmailAndPassword(email, password);
console.log(email, password);
// Redirect to a specified route
if(redirect) {
// context.$router.go(redirect)
// console.log(context.$router);
}
promise
.then(user => {
self.user.authenticated = true
self.user.message = false
})
.catch(e => {
self.user.message = e.message
console.log(e);
})
},
signup(context, creds, redirect) {
console.log('Sign Up...');
let email = creds.email
let password = creds.password
let promise = auth.createUserWithEmailAndPassword(email, password);
promise
.then(user => {
console.log(user);
self.user.message = false
})
.catch(e => {
self.user.message = e.message
console.log(e);
})
},
logout() {
let self = this
auth.signOut().then(function() {
// Sign-out successful.
console.log('Log-out successful');
self.user.authenticated = false
}, function(error) {
// An error happened.
console.log('Log-out error');
});
},
provider(context, creds, redirect) {
let provider = new firebase.auth.GoogleAuthProvider()
auth.signInWithPopup(provider).then(function(result) {
// Accounts successfully linked.
var credential = result.credential;
var user = result.user;
// ...
console.log(credential);
console.log(user.photoURL);
}).catch(function(error) {
// Handle Errors here.
// ...
console.log(error);
});
},
checkAuth() {
let self = this
auth.onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
console.log('Connect:', user);
self.user.authenticated = true
self.user.data = user
} else {
// No user is signed in.
console.log('No connect:');
self.user.authenticated = false
self.user.data = null
}
});
}
}
I can not understand how to test it in Javascript...
(I make application to vue.js)
Thank you!
I'm a bit late to the party here but may as well answer this for anyone looking.
The current method for assigning roles to users with Firebase is to use custom claims. To do this you mint your own JWTs and add in the custom claims at this point. You can use Firebase Functions to do this or you could do this on your own server.
You can see the documentation here.