Getting an error "The email address is badly formatted." when trying to use Vue.js with firebase to create a login page.
Here's my code:
<template>
<div class = "sign-up">
<p> Let's create a new account</p>
<input type="email" v-model="email" placeholder="Email"> <br>
<input type="password" v-model="password" placeholder="Password"> <br>
<button v-on:click="signUp">Sign Up</button>
<br>
</div>
</template>
<script>
import firebase from 'firebase'
export default {
name:'Signup',
data: function() {
return {
email: '',
password: '',
}
},
methods: {
signUp: function() {
firebase.auth().createUserWithEmailAndPassword(this.email, this.password).then(
function (user) {
alert('Your account has been created')
},
function(error) {
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
});
}
}
}
</script>
I did make sure that I have enabled the authentication part at the firebase console .
Don't know why still get this error
Help please
Thank God I solved it.
The problem is solved by adding
firebase.initializeApp(config);
right after
import firebase from 'firebase'
since I have already initialize Firebase in other files
the problem might be caused by javascript loading asynchronously .
This works well. I tired to solve your ones. I have brought official firebase auth sample. Your user was not defined and while importing you must have use {} to prevent .auth() error.
<template>
<div class = "sign-up">
<p> Let's create a new account</p>
<input type="email" v-model="email" placeholder="Email">
<input type="password" v-model="password" placeholder="Password">
<button v-on:click="signUp">Sign Up</button>
</div>
</template>
<script>
import {fb} from '../firebase';
export default {
name:'Signup',
data() {
return {
email: "",
password: "",
}
},
methods: {
signUp: function() {
fb.auth().createUserWithEmailAndPassword(this.email, this.password)
.catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
if (errorCode == 'auth/weak-password') {
alert('The password is too weak.');
} else {
alert(errorMessage);
}
console.log(error);
});
}
}
}
</script>
Related
I'm curious why I can't pass input data using "base-input",
But when I using "input" I can pass my data.
This is my front-end code:
<form #submit.prevent="pressed">
<base-input placeholder="email" addon-left-icon="ni ni-email-83" type="email" v-model="email"/>
<base-input formClasses="input-group-alternative mb-3" placeholder="Password" type="password" addon-left-icon="ni ni-lock-circle-open" v-model="password"/>
<div class="text-center">
<button type="submit">Login</button>
</div>
</form>
This is my back-end script:
methods: {
pressed() {
firebase
.auth()
.signInWithEmailAndPassword(this.email, this.password)
.then(data => {
console.log(data)
this.$router.replace({ name: "home" });
})
.catch(err => {
this.error = err.message;
alert(err.message)
console.log(err.message)
console.log(this.email, this.password)
});
}
}
Technically, you are not sending your data to database SQL, try connect your firebase jquery to SQL/Dolphin
if you try just using JS/firebase:
passing/allow bypass auth would be:
$("#pass-submit").click(function () {
if (pass.val() == "password") {
lock1.fadeOut("fast", function () {
lock2.fadeIn("slow");
});
} else {
lock1.fadeOut("fast", function () {
wrongPg.fadeIn("slow");
});
}
});
$(pass).keypress(function (e) {
if (e.which == 13) {
$("#pass-submit").click();
}
});
Sample Link of using Passing JS:
Click Here
I'm getting these two errors
TypeError: firebase__WEBPACK_IMPORTED_MODULE_2__.default.firestore(...).collections is not a function
Cannot read property 'user' of undefined
when trying to add user profile data into firebase collections 'profiles' when signing up. Please help.
This is the template section of my 'EditProfile' page.
<template>
<div class="edit-profile">
<section>
<div class="column">
<div class="header" style="font-weight:bold">
Profile Settings
</div>
<div>
<input
type="text"
class="form-control"
placeholder="Full name"
v-model="profile.name"
/>
<input
type="phone"
class="form-control"
placeholder="Phone"
v-model="profile.phone"
/>
<input
type="text"
class="form-control"
placeholder="Billing Address"
v-model="profile.address"
/>
<input
type="text"
class="form-control"
placeholder="Postcode"
v-model="profile.postcode"
/>
<button
#click="updateProfile"
>
Save changes
</button>
</div>
</div>
</section>
</div>
</template>
Here is my script for the above EditProfile page.I haven't really added the code for edit profile bcuz I'm still unaware on how to do that
<script>
import firebase from "firebase";
require("firebase/auth");
export default {
name: "EditProfile",
data() {
return {
profile: {
fullName: null,
phone: null,
address: null,
postcode: null,
},
};
},
methods: {
updateProfile() {},
},
};
</script>
Here is the template for 'RegisterCustomer' page. Here I will be signing up new users.
<template>
<div class="row">
<transition type="text/x-template" id="register-customer">
<div class="modal-mask">
<div class="modal-wrapper">
<div>
<div class="modal-body">
<slot name="body">
<div class="row">
<div class="col-sm-4 off-set">
<form>
<div #click="$emit('close')">
<span class="close">✖</span>
</div>
<h3>Sign up</h3>
<br />
<div class="form-group">
<input
type="text"
class="form-control"
placeholder="fullName"
v-model="fullName"
/>
</div>
<div class="form-group">
<input
type="email"
class="form-control"
placeholder="Email"
v-model="email"
/>
</div>
<div class="form-group">
<input
type="password"
class="form-control"
placeholder="Password"
v-model="password"
#keyup.enter="
onSubmit();
$emit('close');
"
/>
</div>
<div class="modal-footer">
<slot name="footer">
<button
class="btn btn-primary"
type="button"
#click.prevent="onSubmit"
#click="$emit('close')"
>
Sign up
</button>
</slot>
</div>
</form>
</div>
</div>
</slot>
</div>
</div>
</div>
</div></transition
>
</div>
</template>
This is my sign up code in my RegisterCustomer page. I want to add user info into my profiles collection. For now I want to pass the fullName data into my profiles collection.
<script>
import firebase from "firebase";
import "firebase/auth";
export default {
name: "RegisterCustomer",
data: () => ({
fullName: "",
email: "",
password: "",
}),
methods: {
async onSubmit() {
try {
var { user } = await firebase
.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.then(() => {
firebase
.firestore()
.collection("profiles")
.doc(user.uid)
.update({
fullName: this.fullName,
});
console.log("Document successfully written.");
})
.then(() => {
alert("Registration successful.");
console.log(user.uid);
})
.catch((error) => {
console.log(error.message);
});
// this.$router.push("/customer");
} catch (error) {
console.log("error occured", error.message);
alert(error.message);
}
},
},
};
</script>
You need to import the Firebase services you are importing along with the core Firebase App as shown:
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
If you don't import Firestore that way, it'll result in similar issue. Although it was a typo in your case, it's "collection".
The second error Cannot read property 'user' of undefined, is probably because you are trying to get user property from a Promise. Try refactoring your code like this:
async onSubmit() {
try {
const { user } = await firebase.auth().createUserWithEmailAndPassword(this.email, this.password)
await firebase.firestore().collection("profiles")
.doc(user.uid)
.update({
fullName: this.fullName,
});
console.log("Document successfully written.");
alert("Registration successful.");
console.log(user.uid);
} catch (error) {
console.log("error occured", error.message);
alert(error.message);
}
},
I figured out the answer. All I had to do was change .update() to .set() when creating the profiles collection in RegisterCustomer.
Here is the script for RegisterCustomer. Hope someone finds this useful.
<script>
import firebase from "firebase";
import "firebase/auth";
import "firebase/firestore";
export default {
name: "RegisterCustomer",
data: () => ({
fullName: null,
email: null,
password: null,
address: null,
postcode: null,
}),
methods: {
async onSubmit() {
try {
firebase
.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.then((cred) => {
return firebase
.firestore()
.collection("profiles")
.doc(cred.user.uid)
.set({
email: this.email,
fullName: this.fullName,
address: this.address,
postcode: this.postcode,
})
.then(() => {
console.log("Document successfully written.");
});
})
.then(() => {
alert("Registration successful.");
})
.catch((error) => {
console.log(error.message);
});
this.$router.push("/customer");
} catch (error) {
console.log("Error", error.message);
alert(error.message);
}
},
},
};
</script>
I am trying to access a data variable called localUser from a function inside of a method function. But as far as I can tell from the error message, I think it just can't access localUser from data.
This is the error message I get:
Uncaught (in promise) TypeError: Cannot set property 'localUser' of undefined at eval (Form.vue?c13f:100) at auth.js:1361
I have marked where the problem is in the code with the comment of:
// THE BUG - cannot access this.localUser
What I've tried:
Using this.$data.localUser
Puting it into a .then function after the firebase.auth().onAuthStateChanged( (user) => {} function like in the code below, which actually worked but I can't do it with .then, I have to do it inside of:
firebase.auth().onAuthStateChanged( (user) => {}
firebase.auth().createUserWithEmailAndPassword(this.email, this.password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorMessage);
}).then(() => {
firebase.auth().onAuthStateChanged( (user) => {
if (user) {
// If already signed in
const db = firebase.firestore();
this.localUser = user;
console.log(this.localUser);
db.collection("users").doc(this.localUser.uid).set({
firstName: this.firstName,
lastName: this.lastName,
student: this.student,
teacher: this.teacher,
email: this.email,
password: this.password
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
}
})
})
The code I use and in which the problem lies on line 96:
<template>
<div id="signup-form-con" v-if="!connected">
<form id="signup-form" #submit.prevent>
<input v-model='firstName' type="text" id="signup-name" placeholder='First name'><br />
<input v-model='lastName' type="text" id="signup-surname" placeholder='Last name'><br />
<input v-model='student' type="checkbox"><span class='checkbox-label'>Student</span>
<input v-model='teacher' type="checkbox"><span class='checkbox-label'>Teacher</span><br />
<input v-model='email' type="email" id="signup-email"><br />
<input v-model='password' type="password" placeholder='Password'>
<input v-model='confirmed' type="password" placeholder='Confirm'><br />
<span>Sign in instead</span>
<button #click='EmailSignIn'>Next</button>
</form>
<div class="auto-signup">
<span id="or-use">Or use</span>
<div class="buttons">
<button id="google-signup" #click='GoogleSignIn'>
<img src="" alt="" id="google-img-signup">
</button>
<button id="facebook-signup" #click='FacebookSignIn'>
<img src="" alt="" id="fb-img-signup">
</button>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Form",
props: {
connected: false
},
data: function() {
return {
localUser: null,
firstName: null,
lastName: null,
student: false,
teacher: false,
email: null,
password: null,
confirmed: null
}
},
methods: {
EmailSignIn: function() {
firebase.auth().createUserWithEmailAndPassword(this.email, this.password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorMessage);
firebase.auth().onAuthStateChanged( (user) => {
if (user) {
// If already signed in
const db = firebase.firestore();
// THE BUG - cannot access this.localUser
this.localUser = user;
console.log(this.localUser);
db.collection("users").doc(this.localUser.uid).set({
firstName: this.firstName,
lastName: this.lastName,
student: this.student,
teacher: this.teacher,
email: this.email,
password: this.password
})
.then(function() {
console.log("Document successfully written!");
})
.catch(function(error) {
console.error("Error writing document: ", error);
});
}
})
}).then(() => {
})
}
</script>
<style scoped lang="sass"></style>
I don't understand why you're executing all of the code (at least all that you show) in an error handler, but the reason you can't access the Vue context is the error handler [reformatted for clarity]:
firebase.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.catch(function(error) {
// all your code is here
})
You can make the context match by changing that to an arrow function:
firebase.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.catch((error) => {
// all your code is here
})
I'm following a tutorial of Vue.js with Firebase.
I'm novice to this and trying to make user account to firebase with Vue.js and I'm getting this error.
Uncaught O {code: "auth/argument-error", message: "createUserWithEmailAndPassword failed: First argument "email" must be a valid string."}
I've already enabled sign-in-method in firebase. Here is my code.
<template>
<div class="signup">
<p>Let's create a new account</p>
<input type="text" v-model="email" placeholder="Email" /><br/>
<input type="password" v-model="password" placeholder="Password" /><br/>
<button v-on:click="signUp">Sign up</button>
<span>or go back to <router-link to="/login">login</router-link>.</span>
</div>
</template>
<script>
import firebase from 'firebase'
export default {
name: 'signup',
data () {
return {
email: '',
password: ''
}
},
methods: {
signUp: () => {
firebase.auth().createUserWithEmailAndPassword(this.email, this.password).then(
(user) => {
alert('Your account has been created!')
},
(err) => {
alert('Opps!' + err.message)
}
);
}
}
}
</script>
When I console.log the email and password in signUp method, I found both the email and password are undefined.
The Problem was arrow functions. Changed ()=> {} to function() {} and now it works. Thanks to #EricGuan's comment.
I'm following along TheMeteorChef's Building a SaaS with Meteor: Stripe which is built with blaze templates. Tried to use react instead but I think I failed somewhere along the way. I've gotten to about half of the part 1 of 2 but enough to test if signing up with plan should work or not. Well, it doesn't work but also doesn't give any errors in console... I have very little experience, just started actually, so I'm hoping I could get some help. Thank you.
~/client/helpers/stripe.js
Meteor.startup(function() {
const stripeKey = Meteor.settings.public.stripe.testPublishableKey;
Stripe.setPublishableKey(stripeKey);
STRIPE = {
getToken: function(domElement, card, callback) {
Stripe.card.createToken(card, function(status, response) {
if(response.error) {
Bert.alert(response.error.message, "danger");
} else {
STRIPE.setToken(response.id, domElement, callback);
}
});
},
setToken: function(token, domElement, callback) {
$(domElement).append($('<input type="hidden" name="stripeToken" />').val(token));
callback();
}
}
});
~/client/components/SignUp.jsx
import React, {Component} from 'react';
import PlanSelectForm from '../components/PlanSelectForm.jsx';
import CreditCardForm from '../components/CreditCardForm.jsx';
export default class SignUp extends Component {
componentDidMount() {
$.validator.addMethod('usernameRegex', function(value, element) {
return this.optional(element) || /^[a-zA-Z0-9-_]+$/i.test(value);
}, "Username must contain only letters, numbers, underscores and dashes.");
$('#application-signup').validate({
rules: {
username: {
required: true,
usernameRegex: true,
minlength: 6
},
emailAddress: {
required: true,
email: true
},
password: {
required: true,
minlength: 6
}
},
messages: {
username: {
required: 'You can\'t leave this empty',
usernameRegex: 'You can use letter, numbers, underscores, and dashes.',
minlength: 'Too short. Use at least 6 characters.'
},
emailAddress: {
required: 'You can\'t leave this empty',
email: 'Email is invalid or already taken.'
},
password: {
required: 'You can\'t leave this empty',
minlength: 'Too short. Use at least 6 characters.'
}
},
handleSubmit: function() {
STRIPE.getToken('#application-signup', {
number: $('[data-stripe="cardNumber"]').val(),
exp_month: $('[data-stripe="expMo"]').val(),
exp_year: $('[data-stripe="expYr"]').val(),
cvc: $('[data-stripe="cvc"]').val()
}, function() {
const customer = {
username: $('[name="username"]').val(),
emailAddress: $('[name="emailAddress"]').val(),
password: $('[name="password"]').val(),
plan: $('[name="selectPlan"]:checked').val(),
token: $('[name="stripeToken"]').val()
};
const submitButton = $('input[type="submit"]').button('loading');
Meteor.call('createTrialCustomer', customer, function(error, response) {
if(error) {
alert(error.reason);
submitButton.button('reset');
} else {
if(response.error) {
alert(response.message);
submitButton.button('reset');
} else {
Meteor.loginWithPassword(customer.emailAddress, customer.password, function(error) {
if(error) {
alert(error.reason);
submitButton.button('reset');
} else {
Router.go('/chart');
submitButton.button('reset');
}
});
}
}
});
});
}
});
}
render() {
console.log(this);
return (
<form id="application-signup" className="signup">
<h4>Account details</h4>
<div className="form-group">
<label for="username">Username</label>
<input type="text"
name="username"
className="form-control"
placeholder="Username" />
</div>
<div className="form-group">
<label for="emailAddress">Email Address</label>
<input type="email"
name="emailAddress"
className="form-control"
placeholder="Email Address" />
</div>
<div className="form-group">
<label for="password">Password</label>
<input type="password"
name="password"
className="form-control"
placeholder="Password" />
</div>
<h4 className="page-header">Payment Information</h4>
<label>Which plan sounds <em>amazing</em>?</label>
<PlanSelectForm />
<div className="form-group">
<CreditCardForm />{/* data={signup} /> */}
</div>
<div className="form-group">
<input type="submit"
className="btn btn-success btn-block"
data-loading-text="Setting up your trial..."
value="Put me on the rocketship" />
</div>
</form>
)
}
}
Note: In the tutorial, TheMeteorChef uses a dynamic template for CreditCardForm with data="signup" context. I think he mentions the CC template will be used again after but I haven't gone that far yet. Anyways, I didn't know what "signup" means... so I left it commented out. If you know, please let me know about that as well.
~/client/components/PlanSelectForm.jsx
import React, {Component} from 'react';
export default class PlanSelectForm extends Component {
componentDidMount() {
const firstPlanItem = $('.select-plan a:first-child');
firstPlanItem.addClass('active');
firstPlanItem.find('input').prop('checked', true);
}
plans() {
return Meteor.settings.public.plans;
}
handleClickItem(e) {
const parent = $(e.target).closest('.list-group-item');
console.log(parent);
parent.addClass('active');
$('.list-group-item').not(parent).removeClass('active');
$('.list-group-item').not(parent).find('input[type="radio"]').prop('checked', false);
parent.find('input[type="radio"]').prop('checked', true);
}
render() {
let plans = this.plans();
if(!plans) {
return(<div>loading...</div>);
}
return (
<div className="list-group select-plan">
{plans.map((plan) => {
return (
<a key={plan.id}
href="#"
className="list-group-item"
onClick={this.handleClickItem.bind(this)}>
<input key={plan.id}
type="radio"
ref="selectPlan"
id={`selectPlan_${plan.id}`}
value={plan.name} />
{plan.name} {plan.amount.usd}/{plan.interval}
</a>
)
})}
</div>
)
}
}
~/client/components/CreditCardForm.jsx
import React, {Component} from 'react';
export default class CreditCardForm extends Component {
render() {
return (
<div>
<div className="row">
<div className="col-xs-12">
<div className="form-group">
<label className="text-success">
<i className="fa fa-lock"></i> Card Number
</label>
<input type="text"
data-stripe="cardNumber"
className="form-control card-number"
placeholder="Card Number" />
</div>
</div>
</div>
<div className="row">
<div className="col-xs-4">
<label>Exp. Mo.</label>
<input type="text"
data-stripe="expMo"
className="form-control exp-month"
placeholder="Exp. Mo." />
</div>
<div className="col-xs-4">
<label>Exp. Yr.</label>
<input type="text"
data-stripe="expYr"
className="form-control exp-year"
placeholder="Exp. Yr." />
</div>
<div className="col-xs-4">
<label>CVC</label>
<input type="text"
data-stripe="cvc"
className="form-control cvc"
placeholder="CVC" />
</div>
</div>
</div>
)
}
}
~/server/signup.js
Meteor.methods({
createTrialCustomer: function(customer) {
check(customer, {
name: String,
emailAddress: String,
password: String,
plan: String,
token: String
});
const emailRegex = new RegExp(customer.emailAddress, 'i');
const usernameRegex = new RegExp(customer.username, 'i');
const lookupEmail = Meteor.users.findOne({'emails.address': emailRegex});
const lookupUser = Meteor.users.findOne({'username': usernameRegex});
if(!lookupEmail) {
if(!lookupUser) {
const newCustomer = new Future();
Meteor.call('stripeCreateCustomer', customer.token, customer.emailAddress, function(error, stripeCustomer) {
if(error) {
console.log(error);
} else {
const customerId = stripeCustomer.id,
plan = customer.plan;
Meteor.call('stripeCreateSubscription', customerId, plan, function(error, response) {
if(error) {
console.log(error);
} else {
try {
const user = Accounts.createUser({
username: customer.username,
email: customer.emailAddress,
password: customer.password
});
const subscription = {
customerId: customerId,
subscription: {
plan: {
name: customer.plan,
used: 0
},
payment: {
card: {
type: stripeCustomer.sources.data[0].brand,
lastFour: stripeCustomer.sources.data[0].last4
},
nextPaymentDue: response.current_period_end
}
}
}
Meteor.users.update(user, {
$set: subscription
}, function(error, response) {
if(error) {
console.log(error);
} else {
newCustomer.return(user);
}
});
} catch(exception) {
newCustomer.return(exception);
}
}
});
}
});
return newCustomer.wait();
} else {
throw new Meteor.Error('username-exists', 'Sorry, that username is already active!');
}
} else {
throw new Meteor.Erro('email-exists', 'Sorry, that email is already active!')
}
},
})
~/server/stripe.js
const secret = Meteor.settings.private.stripe.testSecretKey;
const Stripe = StripeAPI(secret);
Meteor.methods({
stripeCreateCustomer: function(token, email) {
check(token, String);
check(email, String);
const stripeCustomer = new Future();
Stripe.customers.create({
source: token,
email: email
}, function(error, customer) {
if(error){
stripeCustomer.return(error);
} else {
stripeCustomer.return(customer);
}
});
return stripeCustomer.wait();
},
stripeCreateSubscription: function(customer, plan) {
check(customer, String);
check(plan, String);
const stripeSubscription = new Future();
Stripe.customers.createSubscription(customer, {
plan: plan
}, function(error, subscription) {
if(error) {
stripeSubscription.return(error);
} else {
stripeSubscription.return(subscription);
}
});
return stripeSubscription.wait();
}
})
packages
"dependencies": {
"meteor-node-stubs": "~0.2.0",
"react": "^15.0.2",
"react-addons-css-transition-group": "^15.0.2",
"react-dom": "^15.0.2",
"react-mounter": "^1.2.0"
},
accounts-base
accounts-password
session
check
random
kadira:flow-router
ultimatejs:tracker-react
meteortoys:allthings
fourseven:scss
fortawesome:fontawesome
themeteorchef:bert
themeteorchef:jquery-validation
momentjs:moment
mrgalaxy:stripe
Thanks for reading, I hope that it wasn't painful.
did you import mrgalaxy:stripe ?
it will be something like
import { StripeAPI } from 'meteor/mrgalaxy:stripe'
I guess.
anw, you can install by npm :
npm install stripe
import Stripe from 'stripe'
then
Stripe('your_secret_key')