How to send email verification using Laravel and React? - javascript

I want to send the user a verification email after they have created their profile. I am using axios and Sanctum to handle the user registration.
In my AuthController.php file I have
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class AuthController extends Controller
{
public function register(Request $request){
$validator = Validator::make($request->all(),[
'name' => 'required|max:40',
'email' => 'required|email|max:200|unique:users,email',
'password' => 'required|min:8',
]);
if($validator->fails()){
return response()->json(['validation_errors'=>messages()]);
}
else{
$user = User::create([
'name'=> $request->name,
'email'=> $request->email,
'password'=> Hash::make($request->password),
]);
$token = $user->createToken($user->email.'_Token')->plainTextToken;
return response()->json([
'status'=>200,
'username'=>$user->name,
'token'=>$token,
'message'=>'Registration Successful',
])->header('Access-Control-Allow-Origin', '*');
}
}
and in the Register.jsx file I have
`
export default function Register() {
const navigate = useNavigate();
const [registerInput, setRegister] = useState({
name: '',
email: '',
password: '',
error_list: [],
})
const handleInput = (e) => {
e.persist();
setRegister({...registerInput, [e.target.name]: e.target.value });
}
const registerSubmit = (e) => {
e.preventDefault();
const data = {
name: registerInput.name,
email: registerInput.email,
password: registerInput.password,
}
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post(`http://localhost:8000/api/register`, data).then(res => {
if(res.data.status === 200)
{
localStorage.setItem('auth_token', res.data.token);
localStorage.setItem('auth_name', res.data.username);
swal("Success",res.data.message,"success");
navigate('/login');
}
else
{
setRegister({...registerInput, error_list: res.data.validation_errors});
}
});
});
}
}
This method works and I can create new users in the table. The thing is I want to authenticate the created user because the project might get filled with bots.

If you want integrate your project email verification:
First you need email or smtp creditionals,
after successfully creating user you should response about need verification message to frontend in your case react (not login page).
After that there are different ways todo verification proccess. Easy way is generateing unique link for verification and send them user email and when entering this url you can set user active after that send user to login page for sign in to account.
Example implement:
https://codeanddeploy.com/blog/laravel/how-to-implement-laravel-8-email-verification

Related

How do I use a JSON file as a database for dummy users in my React Hooks e-commerce app?

I am creating a frontend dummy e-commerce app. I have created a login page, and the idea is to link the JSON database of users which all have a unique username, password and ID and when you try to login with the parameters you get the Login successful message if there is a user with those parameters in the JSON, and if there is not you get the Fail message. Below is my source code for the login page. For now I have just made a simple if user = user#gmail.com and password = user password, then you get the success message, but the idea is to use the database for multiple user options. The JSON file will be a basic array of user objects.
P.S. stack overflow wont let me post the code unless I put constant and be grammatically correct so I had to separate the use State use navigate and so on
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [valid, setValid] = useState(false)
const [success, setSuccess] = useState(false)
const navigate = useNavigate()
const handle Submit = (e) => {
if (email === 'user#gmail.com' && password === 'user password') {
setValid(true)
setSuccess(true)
setTimeout(() => {
navigate('/')
},3000)
}
e.preventDefault()
}
}
I will imagine your users array is like so per your description
const users = [
{ id: 1, name: 'John',email: 'user1#gmail.com', password: '123456' },
{ id: 2, name: 'Pete' , email: 'user2#gmail.com', password: '123456' },
{ id: 3, name: 'Mary' , email: 'user3#gmail.com', password: '123456' },
];
your submit function will be like so
const handleSubmit = (e) => {
e.preventDefault();
const user = users.find((user) => user.email === email && user.password === password);
if (user) {
// login success
}
else {
// login failed
}
}
this will check if the user info exists in your JSON data or not
you can replace the login success comment and failure wth your specific logic
You can install the package json-server https://github.com/typicode/json-server or maybe another package that does the same thing.

Is their any function signupwithphonenumber in firebase just like signupwithemailandpassword? (for web) I want to make user register with his creds

So ,I am an newbie in firebase and working on an team project. What client wants us to do is make user login with phonenumber and otp.
First, I managed to login the user using this code as follows
import React, { useState } from "react";
import { RecaptchaVerifier, signInWithPhoneNumber } from "firebase/auth";
import { auth } from "../../firebase/config";
const SignInWithNumber = () => {
const [phone, setphone] = useState();
const [otp, setotp] = useState();
const handleRecaptcha = () => {
window.recaptchaVerifier = new RecaptchaVerifier(
"sign-in-button",
{
size: "invisible",
callback: (response) => {
// reCAPTCHA solved, allow signInWithPhoneNumber.
},
},
auth
);
};
const handleSubmitNumber = (e) => {
e.preventDefault();
if (phone >= 10) {
console.log(phone);
handleRecaptcha();
const phoneNumber = "+91" + phone;
const appVerifier = window.recaptchaVerifier;
signInWithPhoneNumber(auth, phoneNumber, appVerifier)
.then((confirmationResult) => {
window.confirmationResult = confirmationResult;
// ...
console.log("otp sent");
})
.catch((error) => {
// Error; SMS not sent
// ...
console.log(error + "SMS not sent");
});
}
};
const handleSubmitOtp = (e) => {
e.preventDefault();
const code = otp;
const x = window.confirmationResult;
x.confirm(code)
.then((result) => {
// User signed in successfully.
const user = result.user;
console.log(user);
// ...
})
.catch((error) => {
// User couldn't sign in (bad verification code?)
// ...
console.log(error);
});
};
const handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
switch (name) {
case "phone":
setphone(value);
break;
case "otp":
setotp(value);
break;
default:
break;
}
};
return (
<div>
<h2>LogIn</h2>
<form onSubmit={handleSubmitNumber}>
<div id="sign-in-button"></div>
<input type="number" name="phone" required onChange={handleChange} />
<button type="submit">Submit</button>
</form>
<h2>Submit OTP</h2>
<form onSubmit={handleSubmitOtp}>
<input type="number" name="otp" required onChange={handleChange} />
<button type="submit">Submit</button>
</form>
</div>
);
};
export default SignInWithNumber;
Now , I am able to login user and get its uid in console but I also want to signup/register the user with his phone number +otp and get his credentials such as name , address etc.
This may be a dumb question but I cant find any solution to this.
Thanks in advance :)
There isn't any sign up method when using phone based auth. If a user doesn't exists then the account will be created (technically a sign up) else user will be logged in to existing account.
You can however check the isNewUser property after authentication to check if user logged in for first time or no.
Checkout Check for isNewUser with Firebase email link auth using modular JS SDK
x.confirm(code)
.then((result) => {
// User signed in successfully.
const { isNewUser } = getAdditionalUserInfo(result)
if (isNewUser) {
// New user - sign up
} else {
// Existing user - log in
}
})
First, the question is not dumb.
Secondly, for a solution, after signing in with phone number successfully, given that the account was just created (a new user), you can now show a form to obtain the user's name and other details.
On submit of this form, save the name to firebase authentication user object with updateProfile. Then save other data to a Firestore document with the user's uid as document id and preferably on the users collection.
On page load, you can check if the user is signed in, if true, check if the user has data in Firestore, if false, show the user the above form, else, continue app usage as you want.

Add username on createUserWithEmailAndPassword in Firebase with React

I want to add the username on the signup of the user and I am using the following code:
//Create Account With Email&Password
const createUser = (email, password, username) => {
return createUserWithEmailAndPassword(auth, email, password).then(() => {
updateProfile(auth.currentUser, {
displayName: username,
});
});
};
This is my useEffect in the same js file
useEffect(() => {
console.log('useEffect');
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
setUser(currentUser);
});
return () => unsubscribe();
}, []);
This code is adding the displayname successfully, but when I redirect to my account page the displayname is not directly showing up and I am getting a memory leak warning from the router-dom. Is there a cleaner and better way to do this?
I believe it's because the account page loads before firebase loads the auth data, you can use something like
onAuthStateChanged(auth,(user)=>{
if(user){
getUserName = auth.currentUser.displayName;
// Load the rest of the page
}
}
at your redirected user page,assuming you are using the right auth state, which you can refer from here https://firebase.google.com/docs/auth/web/auth-state-persistence?authuser=0

how to create a user with firebase without signing in [duplicate]

So I have this issue where every time I add a new user account, it kicks out the current user that is already signed in. I read the firebase api and it said that "If the new account was created, the user is signed in automatically" But they never said anything else about avoiding that.
//ADD EMPLOYEES
addEmployees: function(formData){
firebase.auth().createUserWithEmailAndPassword(formData.email, formData.password).then(function(data){
console.log(data);
});
},
I'm the admin and I'm adding accounts into my site. I would like it if I can add an account without being signed out and signed into the new account. Any way i can avoid this?
Update 20161110 - original answer below
Also, check out this answer for a different approach.
Original answer
This is actually possible.
But not directly, the way to do it is to create a second auth reference and use that to create users:
var config = {apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com"};
var secondaryApp = firebase.initializeApp(config, "Secondary");
secondaryApp.auth().createUserWithEmailAndPassword(em, pwd).then(function(firebaseUser) {
console.log("User " + firebaseUser.uid + " created successfully!");
//I don't know if the next statement is necessary
secondaryApp.auth().signOut();
});
If you don't specify which firebase connection you use for an operation it will use the first one by default.
Source for multiple app references.
EDIT
For the actual creation of a new user, it doesn't matter that there is nobody or someone else than the admin, authenticated on the second auth reference because for creating an account all you need is the auth reference itself.
The following hasn't been tested but it is something to think about
The thing you do have to think about is writing data to firebase. Common practice is that users can edit/update their own user info so when you use the second auth reference for writing this should work. But if you have something like roles or permissions for that user make sure you write that with the auth reference that has the right permissions. In this case, the main auth is the admin and the second auth is the newly created user.
Update 20161108 - original answer below
Firebase just released its firebase-admin SDK, which allows server-side code for this and other common administrative use-cases. Read the installation instructions and then dive into the documentation on creating users.
original answer
This is currently not possible. Creating an Email+Password user automatically signs that new user in.
I just created a Firebase Function that triggers when a Firestore document is Created (with rules write-only to admin user). Then use admin.auth().createUser() to create the new user properly.
export const createUser = functions.firestore
.document('newUsers/{userId}')
.onCreate(async (snap, context) => {
const userId = context.params.userId;
const newUser = await admin.auth().createUser({
disabled: false,
displayName: snap.get('displayName'),
email: snap.get('email'),
password: snap.get('password'),
phoneNumber: snap.get('phoneNumber')
});
// You can also store the new user in another collection with extra fields
await admin.firestore().collection('users').doc(newUser.uid).set({
uid: newUser.uid,
email: newUser.email,
name: newUser.displayName,
phoneNumber: newUser.phoneNumber,
otherfield: snap.get('otherfield'),
anotherfield: snap.get('anotherfield')
});
// Delete the temp document
return admin.firestore().collection('newUsers').doc(userId).delete();
});
You can Algo use functions.https.onCall()
exports.createUser= functions.https.onCall((data, context) => {
const uid = context.auth.uid; // Authorize as you want
// ... do the same logic as above
});
calling it.
const createUser = firebase.functions().httpsCallable('createUser');
createUser({userData: data}).then(result => {
// success or error handling
});
Swift 5: Simple Solution
First store the current user in a variable called originalUser
let originalUser = Auth.auth().currentUser
Then, in the completion handler of creating a new user, use the updateCurrentUser method to restore the original user
Auth.auth().updateCurrentUser(originalUser, completion: nil)
Here is a simple solution using web SDKs.
Create a cloud function (https://firebase.google.com/docs/functions)
import admin from 'firebase-admin';
import * as functions from 'firebase-functions';
const createUser = functions.https.onCall((data) => {
return admin.auth().createUser(data)
.catch((error) => {
throw new functions.https.HttpsError('internal', error.message)
});
});
export default createUser;
Call this function from your app
import firebase from 'firebase/app';
const createUser = firebase.functions().httpsCallable('createUser');
createUser({ email, password })
.then(console.log)
.catch(console.error);
Optionally, you can set user document information using the returned uid.
createUser({ email, password })
.then(({ data: user }) => {
return database
.collection('users')
.doc(user.uid)
.set({
firstname,
lastname,
created: new Date(),
});
})
.then(console.log)
.catch(console.error);
I got André's very clever workaround working in Objective-C using the Firebase iOS SDK:
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"GoogleService-Info" ofType:#"plist"];
FIROptions *secondaryAppOptions = [[FIROptions alloc] initWithContentsOfFile:plistPath];
[FIRApp configureWithName:#"Secondary" options:secondaryAppOptions];
FIRApp *secondaryApp = [FIRApp appNamed:#"Secondary"];
FIRAuth *secondaryAppAuth = [FIRAuth authWithApp:secondaryApp];
[secondaryAppAuth createUserWithEmail:user.email
password:user.password
completion:^(FIRUser * _Nullable user, NSError * _Nullable error) {
[secondaryAppAuth signOut:nil];
}];
Update for Swift 4
I have tried a few different options to create multiple users from a single account, but this is by far the best and easiest solution.
Original answer by Nico
First Configure firebase in your AppDelegate.swift file
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
FirebaseApp.configure(name: "CreatingUsersApp", options: FirebaseApp.app()!.options)
return true
}
Add the following code to action where you are creating the accounts.
if let secondaryApp = FirebaseApp.app(name: "CreatingUsersApp") {
let secondaryAppAuth = Auth.auth(app: secondaryApp)
// Create user in secondary app.
secondaryAppAuth.createUser(withEmail: email, password: password) { (user, error) in
if error != nil {
print(error!)
} else {
//Print created users email.
print(user!.email!)
//Print current logged in users email.
print(Auth.auth().currentUser?.email ?? "default")
try! secondaryAppAuth.signOut()
}
}
}
}
You can use firebase function for add users.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const cors = require('cors')({
origin: true,
});
exports.AddUser = functions.https.onRequest(( req, res ) => {
// Grab the text parameter.
cors( req, res, () => {
let email = req.body.email;
let passwd = req.body.passwd;
let role = req.body.role;
const token = req.get('Authorization').split('Bearer ')[1];
admin.auth().verifyIdToken(token)
.then(
(decoded) => {
// return res.status(200).send( decoded )
return creatUser(decoded);
})
.catch((err) => {
return res.status(401).send(err)
});
function creatUser(user){
admin.auth().createUser({
email: email,
emailVerified: false,
password: passwd,
disabled: false
})
.then((result) => {
console.log('result',result);
return res.status(200).send(result);
}).catch((error) => {
console.log(error.message);
return res.status(400).send(error.message);
})
}
});
});
CreateUser(){
//console.log('Create User')
this.submitted = true;
if (this.myGroup.invalid) {
return;
}
let Email = this.myGroup.value.Email;
let Passwd = this.myGroup.value.Passwd;
let Role = 'myrole';
let TechNum = this.myGroup.value.TechNum;
let user = JSON.parse(localStorage.getItem('user'));
let role = user.role;
let AdminUid = user.uid;
let authToken = user.stsTokenManager.accessToken;
let httpHeaders = new HttpHeaders().set('Authorization', 'Bearer ' + authToken);
let options = { headers: httpHeaders };
let params = { email:Email,passwd:Passwd,role:Role };
this.httpClient.post('https://us-central1-myproject.cloudfunctions.net/AddUser', params, options)
.subscribe( val => {
//console.log('Response from cloud function', val );
let createdUser:any = val;
//console.log(createdUser.uid);
const userRef: AngularFirestoreDocument<any> = this.afs.doc(`users/${createdUser.uid}`);
const userUpdate = {
uid: createdUser.uid,
email: createdUser.email,
displayName: null,
photoURL: null,
emailVerified: createdUser.emailVerified,
role: Role,
TechNum:TechNum,
AccountAccess:this.AccountAccess,
UserStatus:'open',
OwnerUid:AdminUid,
OwnerUidRole:role,
RootAccountAccess:this.RootAccountAccess
}
userRef.set(userUpdate, {
merge: false
});
this.toastr.success('Success, user add','Success');
this.myGroup.reset();
this.submitted = false;
},
err => {
console.log('HTTP Error', err.error)
this.toastr.error(err.error,'Error')
},
() => console.log('HTTP request completed.')
);
}
On the web, this is due to unexpected behavior when you call createUserWithEmailAndPassword out of the registration context; e.g. inviting a new user to your app by creating a new user account.
Seems like, createUserWithEmailAndPassword method triggers a new refresh token and user cookies are updated too. (This side-effect is not documented)
Here is a workaround for Web SDK:
After creating the new user;
firebase.auth().updateCurrentUser (loggedInUser.current)
provided that you initiate loggedInUser with the original user beforehand.
Hey i had similar problem ,trying to create users through admin , as it is not possible to signUp user without signIn ,I created a work around ,adding it below with steps
Instead of signup create a node in firebase realtime db with email as key (firebase do not allow email as key so I have created a function to generate key from email and vice versa, I will attach the functions below)
Save a initial password field while saving user (can even hash it with bcrypt or something, if you prefer though it will be used one time only)
Now Once user try to login check if any node with that email (generate key from email) exist in the db and if so then match the password provided.
If the password matched delete the node and do authSignUpWithEmailandPassword with provided credentials.
User is registered successfully
//Sign In
firebaseDB.child("users").once("value", (snapshot) => {
const users = snapshot.val();
const userKey = emailToKey(data.email);
if (Object.keys(users).find((key) => key === userKey)) {
setError("user already exist");
setTimeout(() => {
setError(false);
}, 2000);
setLoading(false);
} else {
firebaseDB
.child(`users`)
.child(userKey)
.set({ email: data.email, initPassword: data.password })
.then(() => setLoading(false))
.catch(() => {
setLoading(false);
setError("Error in creating user please try again");
setTimeout(() => {
setError(false);
}, 2000);
});
}
});
//Sign Up
signUp = (data, setLoading, setError) => {
auth
.createUserWithEmailAndPassword(data.email, data.password)
.then((res) => {
const userDetails = {
email: res.user.email,
id: res.user.uid,
};
const key = emailToKey(data.email);
app
.database()
.ref(`users/${key}`)
.remove()
.then(() => {
firebaseDB.child("users").child(res.user.uid).set(userDetails);
setLoading(false);
})
.catch(() => {
setLoading(false);
setError("error while registering try again");
setTimeout(() => setError(false), 4000);
});
})
.catch((err) => {
setLoading(false);
setError(err.message);
setTimeout(() => setError(false), 4000);
});
};
//Function to create a valid firebase key from email and vice versa
const emailToKey = (email) => {
//firebase do not allow ".", "#", "$", "[", or "]"
let key = email;
key = key.replace(".", ",0,");
key = key.replace("#", ",1,");
key = key.replace("$", ",2,");
key = key.replace("[", ",3,");
key = key.replace("]", ",4,");
return key;
};
const keyToEmail = (key) => {
let email = key;
email = email.replace(",0,", ".");
email = email.replace(",1,", "#");
email = email.replace(",2,", "$");
email = email.replace(",3,", "[");
email = email.replace(",4,", "]");
return email;
};
If you want to do it in your front end create a second auth reference use it to create other users and sign out and delete that reference. If you do it this way you won't be signed out when creating a new user and you won't get the error that the default firebase app already exists.
const createOtherUser =()=>{
var config = {
//your firebase config
};
let secondaryApp = firebase.initializeApp(config, "secondary");
secondaryApp.auth().createUserWithEmailAndPassword(email, password).then((userCredential) => {
console.log(userCredential.user.uid);
}).then(secondaryApp.auth().signOut()
)
.then(secondaryApp.delete()
)
}
Update 19.05.2022 - using #angular/fire (latest available = v.7.3.0)
If you are not using firebase directly in your app, but use e.g. #angular/fire for auth purposes only, you can use the same approach as suggested earlier as follows with the #angular/fire library:
import { Auth, getAuth, createUserWithEmailAndPassword } from '#angular/fire/auth';
import { deleteApp, initializeApp } from '#angular/fire/app';
import { firebaseConfiguration } from '../config/app.config'; // <-- Your project's configuration here.
const tempApp = initializeApp(firebaseConfiguration, "tempApp");
const tempAppAuth = getAuth(tempApp);
await createUserWithEmailAndPassword(tempAppAuth, email, password)
.then(async (newUser) => {
resolve( () ==> {
// Do something, e.g. add user info to database
});
})
.catch(error => reject(error))
.finally( () => {
tempAppAuth.signOut()
.then( () => deleteApp(tempApp));
});
The Swift version:
FIRApp.configure()
// Creating a second app to create user without logging in
FIRApp.configure(withName: "CreatingUsersApp", options: FIRApp.defaultApp()!.options)
if let secondaryApp = FIRApp(named: "CreatingUsersApp") {
let secondaryAppAuth = FIRAuth(app: secondaryApp)
secondaryAppAuth?.createUser(...)
}
Here is a Swift 3 adaptaion of Jcabrera's answer :
let bundle = Bundle.main
let path = bundle.path(forResource: "GoogleService-Info", ofType: "plist")!
let options = FIROptions.init(contentsOfFile: path)
FIRApp.configure(withName: "Secondary", options: options!)
let secondary_app = FIRApp.init(named: "Secondary")
let second_auth = FIRAuth(app : secondary_app!)
second_auth?.createUser(withEmail: self.username.text!, password: self.password.text!)
{
(user,error) in
print(user!.email!)
print(FIRAuth.auth()?.currentUser?.email ?? "default")
}
If you are using Polymer and Firebase (polymerfire) see this answer: https://stackoverflow.com/a/46698801/1821603
Essentially you create a secondary <firebase-app> to handle the new user registration without affecting the current user.
Android solution (Kotlin):
1.You need FirebaseOptions BUILDER(!) for setting api key, db url, etc., and don't forget to call build() at the end
2.Make a secondary auth variable by calling FirebaseApp.initializeApp()
3.Get instance of FirebaseAuth by passing your newly created secondary auth, and do whatever you want (e.g. createUser)
// 1. you can find these in your project settings under general tab
val firebaseOptionsBuilder = FirebaseOptions.Builder()
firebaseOptionsBuilder.setApiKey("YOUR_API_KEY")
firebaseOptionsBuilder.setDatabaseUrl("YOUR_DATABASE_URL")
firebaseOptionsBuilder.setProjectId("YOUR_PROJECT_ID")
firebaseOptionsBuilder.setApplicationId("YOUR_APPLICATION_ID") //not sure if this one is needed
val firebaseOptions = firebaseOptionsBuilder.build()
// indeterminate progress dialog *ANKO*
val progressDialog = indeterminateProgressDialog(resources.getString(R.string.progressDialog_message_registering))
progressDialog.show()
// 2. second auth created by passing the context, firebase options and a string for secondary db name
val newAuth = FirebaseApp.initializeApp(this#ListActivity, firebaseOptions, Constants.secondary_db_auth)
// 3. calling the create method on our newly created auth, passed in getInstance
FirebaseAuth.getInstance(newAuth).createUserWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener { it ->
if (it.isSuccessful) {
// 'it' is a Task<AuthResult>, so we can get our newly created user from result
val newUser = it.result.user
// store wanted values on your user model, e.g. email, name, phonenumber, etc.
val user = User()
user.email = email
user.name = name
user.created = Date().time
user.active = true
user.phone = phone
// set user model on /db_root/users/uid_of_created_user/, or wherever you want depending on your structure
FirebaseDatabase.getInstance().reference.child(Constants.db_users).child(newUser.uid).setValue(user)
// send newly created user email verification link
newUser.sendEmailVerification()
progressDialog.dismiss()
// sign him out
FirebaseAuth.getInstance(newAuth).signOut()
// DELETE SECONDARY AUTH! thanks, Jimmy :D
newAuth.delete()
} else {
progressDialog.dismiss()
try {
throw it.exception!!
// catch exception for already existing user (e-mail)
} catch (e: FirebaseAuthUserCollisionException) {
alert(resources.getString(R.string.exception_FirebaseAuthUserCollision), resources.getString(R.string.alertDialog_title_error)) {
okButton {
isCancelable = false
}
}.show()
}
}
}
For Android, i suggest a simpler way to do it, without having to provide api key, application id...etc by hand by just using the FirebaseOptions of the default instance.
val firebaseDefaultApp = Firebase.auth.app
val signUpAppName = firebaseDefaultApp.name + "_signUp"
val signUpApp = try {
FirebaseApp.initializeApp(
context,
firebaseDefaultApp.options,
signUpAppName
)
} catch (e: IllegalStateException) {
// IllegalStateException is throw if an app with the same name has already been initialized.
FirebaseApp.getInstance(signUpAppName)
}
// Here is the instance you can use to sign up without triggering auth state on the default Firebase.auth
val signUpFirebaseAuth = Firebase.auth(signUpApp)
How to use ?
signUpFirebaseAuth
.createUserWithEmailAndPassword(email, password)
.addOnSuccessListener {
// Optional, you can send verification email here if you need
// As soon as the sign up with sign in is over, we can sign out the current user
firebaseAuthSignUp.signOut()
}
.addOnFailureListener {
// Log
}
My solution to this question is to store the User Name/Email and password in a static class and then add a new user log out the new user and immediately log in as the admin user(id pass you saved). Works like a charm for me :D
This is a version for Kotlin:
fun createUser(mail: String, password: String) {
val opts = FirebaseOptions.fromResource(requireContext())
if (opts == null) return
val app = Firebase.initialize(requireContext(), opts, "Secondary")
FirebaseAuth.getInstance(app)
.createUserWithEmailAndPassword(mail, password)
.addOnSuccessListener {
app.delete()
doWhateverWithAccount(it)
}.addOnFailureListener {
app.delete()
showException(it)
}
}
It uses the configuration from your default Firebase application instance, just under a different name.
It also deletes the newly created instance afterwards, so you can call this multiple times without any exception about already existing Secondary application.

Firebase current user update Phone Number

I am using firebase Auth and I have a form with two fields name and phone number and onsubmit method and I want to update currently logged in user's phone number and name. But its not updating the phone number on submit. Only successfully updating the user's displayname. Please check the code below. onUpdateProfile is the form submit function.
<template>
<form #submit.prevent="onUpdateProfile">
<input type="text" v-model="profile.name" placeholder="Enter Your Name..." />
<input type="text" v-model="profile.phonenumber" placeholder="Enter Your phone..." />
<button type="submit">submit</button>
</form>
</template>
methods: {
onUpdateProfile() {
firebase.auth().onAuthStateChanged(user => {
if (user) {
//Getting Current User
let user = firebase.auth().currentUser;
user
.updateProfile({
displayName: this.profile.name,
phoneNumber: this.profile.phoneNumber
})
.then(() => {console.log('success})
.catch(error => {console.log(error});
//Updating User other details on submit
} else {
}
});
}
}
data() {
return {
profile: {
name: "",
phonenumber: ""
}
};
}
You can't use updateProfile to update the phoneNumber. You have to use the updatePhoneNumber API as Firebase Auth always requires the phone number to be verified before saving it on a user.
This is similar to signInWithPhoneNumber.
const phoneNumber = getPhoneNumberFromUserInput();
const appVerifier = new firebase.auth.RecaptchaVerifier(...);
firebase.auth().currentUser.updatePhoneNumber(phoneNumber, appVerifier)
.then((confirmationResult) => {
// SMS sent. Prompt user to type the code from the message, then complete
// verification by calling confirmationResult.confirm(code).
...
return confirmationResult.confirm(smsCode);
}).then((userCredential) => {
// Phone set on the user.
}).catch((error) => {
// Error occurred.
});
This worked for me:
async function save(phone: string, e) {
e.preventDefault();
const { currentUser:fuser } = firebase.auth();
if(fuser && fuser.phoneNumber !== phone) {
try {
const verifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
callback: (response) => console.log('callback', response),
size: 'invisible',
});
const phoneProvider = new firebase.auth.PhoneAuthProvider();
const id = await phoneProvider.verifyPhoneNumber(phone, verifier);
const code = window.prompt('Bitte zugeschickten Code eingeben');
const cred = firebase.auth.PhoneAuthProvider.credential(id, code);
await fuser.updatePhoneNumber(cred);
console.log('phone number changed', id, cred, fuser);
setSuccess(true);
} catch(e) {
console.error(e);
}
}
}
UPDATE
According to the Firebase documentation, it looks like you can only update phone number if you are using firebase-admin. Without it you can only update basic information, such as the user's display name and profile photo URL.
If I am wrong please feel free to correct me.
https://firebase.google.com/docs/auth/admin/manage-users#update_a_user
https://firebase.google.com/docs/auth/web/manage-users#update_a_users_profile
you are using different names;
in template you have this:
v-model="profile.phonenumber"
and in the onUpdateProfile() method
phoneNumber: this.profile.phoneNumber

Categories

Resources