Meteor Semantic UI react: Modifying user account information - meteor

In creating a user settings page, I wanted display current user account email and password and give the user the ability to change both.
I read up on https://guide.meteor.com/accounts.html#displaying-user-data, but I'm still confused about how the data is handled.
Would somebody be able to point me in the right direction? Attached below is a code snippet of how our sign-up page handles the data.
/** Handle Signup submission. Create user account and a profile entry, then redirect to the home page. */
submit = () => {
const { email, password } = this.state;
Accounts.createUser({ email, username: email, password }, (err) => {
if (err) {
this.setState({ error: err.reason });
} else {
this.setState({ error: '', redirectToReferer: true });
}
});
}

Related

Firebase Login with Google: Only let one pre existing email in

Its a admin panel and there only one email that need to be logged in to the admin panel. Right now every email gets logged in to the panel. I've manually added a user (email and password) to the 'Users' in Firebase. Now I want to only let that email in using Google Auth Provider. Is there a way to do this? There's a provider.setCustomParameters() but that's only for email domains, not for complete email. Right now my function looks like this;
const signInWithGoogle = async () => {
const provider = new GoogleAuthProvider();
try {
auth.signInWithPopup(provider).then((result) => {
});
} catch (error) {}
};
I want something like this (this doesn't work)
provider.setCustomParameters({
email: "example#gmail.com" //only let in this email user
})

Simple email verification in React Native and Firebase

I made a simple registration form in React Native. I want to check if the email is valid or not by sending a verification code to it. I read many similar questions but I couldn't combine them with my code because I'm new to React Native. Can anyone help me do that without just posting a link for another answer?
Here's my registration code:
export class Register extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: '',
name: '',
lastname: ''
}
this.onSignUp = this.onSignUp.bind(this)
}
onSignUp(){
if(
this.state.email != '' &&
this.state.password != '' &&
this.state.name != ''
){
const { email, password, name } = this.state;
firebase.auth().createUserWithEmailAndPassword(email, password)
.then((result) => {
firebase.firestore().collection("Users")
.doc(firebase.auth().currentUser.uid)
.set({
name,
email
})
console.log(result)
})
.catch((error) => {
console.log(error)
})
}
else{
alert("Please fill the empty spaces!");
}
}
render() { form body }
You cannot verify user email using before creating the account by using Client SDK only. If you need to do that, you will have to use Cloud Functions (or your own server) along with a third party email sending service and implement your own logic.
However you can verify the email of user by sending the user a verification email like this:
//new user created
var user = firebase.auth().currentUser;
user.sendEmailVerification().then(function() {
// Email sent.
}).catch(function(error) {
// An error happened.
});
This will send an email to your user containing a verification link. Thereafter you can use emailVerified property to check if user has verified their email to restrict access to data like:
if (user.emailVerified) {
// process
} else {
alert("Please verify your email")
}
In you case, the code would look like:
const { email, password, name } = this.state;
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(async (result) => {
await firebase.firestore().collection("Users")
.doc(firebase.auth().currentUser.uid)
.set({
name,
email
})
await user.sendEmailVerification()
console.log("Verification Email Sent")
})

Need to visit a registration link multiple times in Cypress

I have a bunch of Cypress tests that are being driven by a fixture file which contains the number of tests I want to run.
As part of my tests. I need to visit a registration link and register a new account.
The problem is that the first time I visit the registration form. It appears fine. But if I go to it again. The new form doesn't show and I only see the regular login form.
I suspect that because I'm running multiple tests from one spec file that Cypress is remembering that I've already visited the page and showing me the log in form.
I know I shouldn't be using the UI to register new accounts. But it's the only solution currently.
/// <reference types="cypress" />
let user;
before(function () {
cy.task("newUser").then((user) => {
user = user;
});
});
const types = require("../fixtures/types");
types.forEach((type) => {
context("Matter Creation", () => {
it("Tests if a Service Agent can create a new matter", () => {
cy.fixture("data").then((data) => {
cy.addNewUser({
userEmail: user.email,
userPassword: user.password,
});
});
});
});
context("User Registration", () => {
it("Tests the registration process from a users perspective", () => {
cy.userRegistration({
userEmail: user.email,
userPassword: user.password,
});
});
it("Tests that users are registered and can sign in", () => {
cy.verifyRegistration({
userEmail: user.email,
userPassword: user.password,
});
});
});
});
Fixed it by moving my before state into my describe block.
It was reusing old data, instead of using new data for every test.

Firebase getIdToken() + React Native + refreshing user database to authenticate email verified user

I am working on a React Native project and using Firebase.
I am trying to get the user to log in after (s)he has verified their email address. I send the user an email on registration, the user clicks on the verification link to verify themselves and then should be able to logon. My current code allows the user to log in post verification but only after I have refreshed the app. I would want the user to login after the verification without refreshing the app.
I found out that I can achieve it using getIdToken() in Firebase. But somehow I can't seem to get it working. Any pointers where and what I am doing wrong? Thanks in Advance.
My code snippet for this function is:
_login = () =>{
var me = this;
firebaseRef.auth().onAuthStateChanged(function(user) {
if(user){
user.getIdToken(forceRefresh).then(function() {
if( firebaseRef.auth().currentUser.emailVerified){
firebaseRef.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(function(){
// some function here, which is working perfectly
},
function(error) {
alert('The username or password is incorrect');
console.log(error);
})
}
else {
alert('Your email has not been verified');
}
},
function(error) {
alert('There is an email verification error');
console.log(error);
})
}
}
)
}
firebase.auth().signInWithEmailAndPassword(email, password)
.then(() => {
if(firebase.auth().currentUser.emailVerified === false) {
Alert.alert('Message')
} else {
Actions.screen()
}})
.catch(erro => Alert.alert(erro);
}

How to add additional information to firebase.auth()

How can I add extra attributes phone number and address to this data set? It seems like Firebase documentation doesn't specify anything about that.
I have implemented the login, register and update using firebase.auth()
Login :
//Email Login
firebase.auth().signInWithEmailAndPassword(email, password).then(
ok => {
console.log("Logged in User",ok.user);
},
error => {
console.log("email/pass sign in error", error);
}
);
Register:
//Sign Up
firebase.auth().createUserWithEmailAndPassword(email, password).then(
ok => {
console.log("Register OK", ok);
},
error => {
console.log("Register error", error);
}
)
Update:
//User Authentication
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$scope.data=user;
} else {
// No user, Redirect to login page
}
});
//Save Function
$scope.save=function(values){
$scope.data.updateProfile({
displayName: "Test User",
email: "test#gmail.com",
/* phone: 123412341,
address: "Temp Address",*/
photoURL: "www.example.com/profile/img.jpg"
}).then(function() {
// Update successful.
}, function(error) {
// An error happened.
});
};
As far as I know, you have to manage the users profiles by yourself if you want to have more fields than the default user provided by Firebase.
You can do this creating a reference in Firebase to keep all the users profiles.
users: {
"userID1": {
"name":"user 1",
"gender": "male"
},
"userID2": {
"name":"user 2",
"gender": "female"
}
}
You can use onAuthStateChanged to detect when the user is logged in, and if it is you can use once() to retrieve user's data
firebaseRef.child('users').child(user.uid).once('value', callback)
Hope it helps
This can be done by directly storing your custom data in Firebase Auth as "custom claims" on each user via the Admin SDK on your backend.
Note this can't be done purely client-side, your server (or you can use a Cloud Function as per the linked guide if you don't already have a server/API set up) needs to make a request through the Admin SDK to securely set the data using the admin.auth().setCustomUserClaims() method:
https://firebase.google.com/docs/auth/admin/custom-claims#defining_roles_via_an_http_request
You could write some code that combines data from firebase auth and firestore document and expose that to the app as a single data entity. To take subscriptions and notify that changes to the whole app, you would be better served with event libraries like Rxjs. Bellow, I wrote the example below using a simple library that implements an event bus.
// auth.js
import { publish } from '#joaomelo/bus'
import { fireauth, firestore } from './init-firebase.js'
const authState = {
userData: null
};
fireauth.onAuthStateChanged(user => {
if (!user) {
authState.userData = null;
publish('AUTH_STATE_CHANGED', { ...authState });
return;
}
// we must be carefull
// maybe this doc does not exists yet
const docRef = firestore
.collection('profiles')
.doc(user.uid);
docRef
// 'set' secures doc creation without
// affecting any preexisting data
.set({}, { merge: true })
.then(() => {
docRef.onSnapshot(doc => {
// the first data load
// and subsequent updates
// will trigger this
authState.userData = {
id: user.uid,
email: user.email,
...doc.data()
};
publish('AUTH_STATE_CHANGED', { ...authState });
});
});
});
// some-place-else.js
import { subscribe } from '#joaomelo/bus'
subscribe('AUTH_STATE_CHANGED',
authState => console.log(authState));
You can expand on that in a post I wrote detailing this solution and also talking about how to update those properties. There is too a small library that encapsulates the answer with some other minor features with code you could check.

Resources