How to delete firebase realtime data while also deleting authenticated user? - javascript

update 2, i logged the errors
update: I changed const db = getDatabase to const db getDatabase()
it printed to the console that the credentials were removed, but when i checked database, they still remain.
plus this error
I am trying to delete the user data as well as the authenticated data. I am successfully deleting the authenticated data, but it leaves the rest of the data in the database untouched. I have tried the following code:
import React from "react";
import { getAuth, deleteUser, onAuthStateChanged } from "firebase/auth";
import { remove, ref, getDatabase } from "firebase/database";
import { connectStorageEmulator } from "firebase/storage";
function DeleteUser() {
const auth = getAuth();
const user = auth.currentUser;
const db = getDatabase;
const del = ()=>{
if (user) {
remove(ref(db,'users'+user.uid))
.then(()=>{
console.log("credentials emoved")
})
.catch((error)=>{
console.log('failed')
});
deleteUser(user)
.then(() => {
console.log("User deleted");
})
.catch((error) => {
console.log("failed");
});
} else {
console.log("user is sighned out");
}
}
return (
<div>
<button onClick={del}>Delete</button>
</div>
);
}
export default DeleteUser;
I am using this bit to try removing the data, but I am getting some errors
remove(ref(db,'users'+user.uid))
.then(()=>{
console.log("credentials emoved")
})
.catch((error)=>{
console.log('failed')
});

The getDatabase() is a function but you are just assigning that to a variable instead of calling it.
const db = getDatabase;
// change that to
const db = getDatabase();
The recent login required essentially means user must have logged in (by entering their password, signing in by Google, etc) recently. If they have been logged in for a while then you'll need to reauthenticate the user (ask them to enter their password if using Email-password auth).
Checkout Firebase: recent login requested for more information.

Related

How to upload document whenever a user signs up in firebase with custom users uid?

I am working with react and firebase ver 9. As firebase offers limited field and I need to send some more data while registering a user. I saw that you can do this while uploading document whenever a user signs up. I have written the code for it but when I run it only users are registered but my document doesn`t get uploaded.
Here`s my code:
import { useState } from "react"
import { auth, db } from "../Authentication/firebaseConfig"
import { createUserWithEmailAndPassword } from "firebase/auth"
import {
collection,
setDoc,
addDoc,doc
} from "firebase/firestore";
export const useSignup = () => {
const [error, setError] = useState(null)
const signup = async (email, password, displayName) => {
setError(null)
const current_user = await createUserWithEmailAndPassword(auth, email, password, displayName);
const uid = current_user.user.uid;
await addDoc(collection(db, "users"), {
uid: uid,
displayName,
email,
})
.then((res) => {
console.log('user signed up:', res.user)
})
.catch((err) => {
setError(err.message)
})
}
return { error, signup }
}
As stated by #Danial, the error was produced by Cloud Firestore Rules that is set to false.
Sample Rule:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if false;
}
}
}
Sample Firestore rule above will prohibit you to read and write to any collection and document. Changing it to true allows the public to read and write to Firestore.

google auth and firebase persistence

heres my log in function, it works it logs you in via google account, but on refresh it does not stay logged in. what am I doing wrong? sorry I have no idea how to format the code to show correctly here.
const provider = new GoogleAuthProvider();
const login = () =>
{setPersistence(auth, browserSessionPersistence)
.then(()=> {
signInWithPopup(auth, provider)
.then((result) => {
const credential = GoogleAuthProvider.credentialFromResult(result);
const token = credential?.accessToken;
// The signed-in user info.
const user = result.user;
//console.log({ credentials, token, user });
})
.then(() => {
setSignIn(true);
})
.catch((error) => {
// Handle Errors here.
const errorCode = error.code;
const errorMessage = error.message;
// The email of the user's account used.
const email = error.email;
// The AuthCredential type that was used.
const credential = GoogleAuthProvider.credentialFromError(error);
//console.log({ errorCode, errorMessage, email, credential });
});
})
};
Firebase automatically restores the user credentials when you restart the app, but your code only responds to the explicit sign in (signInWithPopup).
To pick up the automatic restore (and other changes in authentication state), you should use an auth state listener as shown in the first code sample in the documentation on getting the current user:
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
var uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});
Since v9, the code has changed.
import { getAuth, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
// User is signed in, see docs for a list of available properties
// https://firebase.google.com/docs/reference/js/firebase.User
const uid = user.uid;
// ...
} else {
// User is signed out
// ...
}
});

How to manage GoogleAuthProvider, signInWithEmailAndPassword and setPersistence in Firebase 9?

I have an application that logs in both by email and password and by GoogleAuth, but after logged in, if the user reloads the page, it logs out.
I'm trying to manage GoogleAuthProvider, signInWithEmailAndPassword and setPersistence. For this example, just follow the login function with Google. I did it as follows:
Login.vue
import { getAuth, setPersistence, inMemoryPersistence, GoogleAuthProvider, signInWithPopup, } from "firebase/auth";
googleSignIn: function() {
const auth = getAuth();
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then(() => {
setPersistence(auth, inMemoryPersistence);
this.$router.push("/");
})
.catch((error) => {
// error messages
}
});
},
I'm trying to apply what I saw here: https://firebase.google.com/docs/auth/web/auth-state-persistence
On the other hand, in the parent component (after logging in), I'm getting the user data without any problems as follows:
Header.vue
import { getAuth, onAuthStateChanged } from "firebase/auth";
export default {
date: () => ({ username: "" }),
created() {
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
if (user) {
this.username = user.displayName;
} else {
this.username = "logged out";
}
});
},
};
EDIT
I'm including the data saved in the application here. Even so, when reloading the user logs out.
On browser environments the default behavior for Firebase Authentication is to persist the user authentication state between page loads, and there is no need to call setPersistence yourself. I recommend removing this call from your code, and leaving it to the Firebase SDK to use its defaults.
That's the intended behavior. You are setting auth persistence to inMemoryPersistencce. The documentation says,
NONE (inMemoryPeristence) indicates that the state will only be stored in memory and will be cleared when the window or activity is refreshed.
Try setting the persistence to SESSION or LOCAL.
If I open dev tools, I can see I am authenticated. The issue seems to be with your redirect here:
router.beforeEach((to, from, next) => {
// This currentUser maybe undefined
const currentUser = getAuth().currentUser;
// ...
else next();
});
Try using onAuthStateChanged() in the beforeEach:
router.beforeEach((to, from, next) => {
const auth = getAuth()
onAuthStateChanged(auth, (user) => {
if (!user) return next("login");
})
})

set display name while creating user with firebase

I have a react app with which I want to handle authentication with firebase.
My code successfully signs up and logs in but i am trying to add extra information on sign up but i have not been successful. I have tried answers [here]: Firebase v3 updateProfile Method and [here]: Firebase user.updateProfile({...}) not working in React App
But they don't seem to work. Below is my code
const SignUp = ({ history }) => {
const handleSignUp = useCallback(
async event => {
event.preventDefault();
const { email, password } = event.target.elements;
try {
let cred = await app
.auth()
.createUserWithEmailAndPassword(email.value, password.value);
await cred.user.updateProfile({
displayName: 'hello'
});
history.push('/');
} catch (error) {
console.log(error);
}
},
[history]
);
Please how do i fix this because currently on the email and username sets? Thanks
In order to change user profile you should use firebase.auth().onAuthStateChanged() function, as follows:
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
} else {
// No user is signed in.
}
});
Then you can get others user properties. Here you can find all info you need. https://firebase.google.com/docs/auth/web/manage-users. Hope it helps.

Using Firebase reauthenticate

I'll appreciate assistance with how to reauthenticate a user in Firebase. I wonder if it makes any sense adding all these great features if the documentation doesn't explain how to use it:
Currently, this is what I'm trying, and it ain't working. Errors as cannot read property 'credential' of undefined
In constructor:
constructor(#Inject(FirebaseApp) firebaseApp: any) {
this.auth = firebaseApp.auth();
console.log(this.auth);
}
then the function
changePassword(passwordData) {
if(passwordData.valid) {
console.log(passwordData.value);
// let us reauthenticate first irrespective of how long
// user's been logged in!
const user = this.auth.currentUser;
const credential = this.auth.EmailAuthProvider.credential(user.email, passwordData.value.oldpassword);
console.log(credential);
this.auth.reauthenticate(credential)
.then((_) => {
console.log('User reauthenticated');
this.auth.updatePassword(passwordData.value.newpassword)
.then((_) => {
console.log('Password changed');
})
.catch((error) => {
console.log(error);
})
})
.catch((error) => {
console.log(error);
})
}
}
The reauthenticate() method is called on a firebase.User, not on firebase.auth.Auth itself.
var user = firebase.app.auth().currentUser;
var credentials = firebase.auth.EmailAuthProvider.credential('puf#firebaseui.com', 'firebase');
user.reauthenticate(credentials);
Update (July 2017):
There are some breaking change in the 4.0 version of the Firebase Web SDK. From the release notes:
BREAKING: firebase.User.prototype.reauthenticate has been removed in favor of firebase.User.prototype.reauthenticateWithCredential.
As far as I can tell the reauthenticateWithCredentialis a drop-in replacement for the old method.
Here's some code that enabled users to (a) reauthenticate in Firebase and (b) change their passwords after reauthenticating for me. I researched for about an hour while writing this, so hopefully it saves someone a minute.
Wrote in VueJS:
changePassword() {
let self = this; // i use "self" to get around scope issues
var user = firebase.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(
this.$store.state.userId, // references the user's email address
this.oldPassword
);
user.reauthenticateWithCredential(credential)
.then(function() {
// User re-authenticated.
user.updatePassword(self.newPassword)
.then(function() {
console.log("Password update successful!");
})
.catch(function(error) {
console.log(
"An error occurred while changing the password:",
error
);
});
})
.catch(function(error) {
console.log("Some kinda bug: ", error);
// An error happened.
});
Slight changes as of May 2019, see more details here. Code is as follows:
var user = firebase.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(user.email, password);
// Prompt the user to re-provide their sign-in credentials
return user.reauthenticateWithCredential(credential);
Call changeEmail("new email","password") in onPressed directly to update the user email with no reauthentication required error
RaisedButton(
onPressed: () {
changeEmail(_emailController.text, _passwordController.text);
}
Future<void> changeEmail(String email, String password) async {
User user = await FirebaseAuth.instance.currentUser;
print(email);
print(password);
try {
try {
var authResult = await user.reauthenticateWithCredential(
EmailAuthProvider.getCredential(
email: user.email,
password: password,
),
);
user.updateEmail(email).then((_) {
print("Succesfull changed email");
_backthrow();
}).catchError((error) {
showAlertDialog(context, error.message);
print("email can't be changed" + error.toString());
});
return null;
} catch (e) {
print("2");
}
} catch (e) {
print(e.message);
showAlertDialog(context, e.message);
}
}
Hers a full example how to reauthenticate with Firebase
var pass = "abcdefg";
var user = firebase.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(user.email, pass);
user.reauthenticateWithCredential(credential).then(() => {
console.log("Its good!");
}).catch((error) => {
console.log(error);
});
Since 2021: If you use Firebase JS API 9.x (the tree shakable version) this is the most recent way:
https://cloud.google.com/identity-platform/docs/web/reauth
With credentials
import { getAuth, reauthenticateWithCredential } from "firebase/auth";
const auth = getAuth();
const user = auth.currentUser;
// todo for you: prompt the user to re-provide their sign-in credentials
const credential = promptForCredentials();
reauthenticateWithCredential(user, credential).then(() => {
// ...
}).catch((error) => {
// ...
});
With popup
import { getAuth, reauthenticateWithPopup, OAuthProvider } from "firebase/auth";
const auth = getAuth();
// todo for you: change to appropriate provider
const provider = new OAuthProvider('apple.com');
reauthenticateWithPopup(auth.currentUser, provider)
.then((result) => {
// ...
})
.catch((error) => {
// ...
});
This is how I re-authenticate a user in Firebase:
import { getAuth, EmailAuthProvider, reauthenticateWithCredential } from "firebase/auth";
const auth = getAuth()
const reauthenticateUser = async (email, password) => {
const user = auth.currentUser;
try {
const credential = EmailAuthProvider.credential(email, password);
await reauthenticateWithCredential(user, credential)
} catch (error) {
Alert.alert("Error", "The email or password is incorrect. Please try again.")
}
}
I was getting that re-authentication error auth/requires-recent-login when saving the primary email.
I couldn't figure out how to implement that poorly documented reauthenticateWithCredential(credential) method, so, I simply logged-out the user and redirected to login page. It's a hack but It works like charm!
firebase.auth().signOut();

Categories

Resources