I wish to check if a user is already logged in through email/password auth via mongodb realm web-sdk. Knowing if the user is logged in will allow me to hide the loggin page from site and instead show a log out button.
So far I've successfully created a user and logged in. Using the code/methods below.
async function registerEmailPassword(email, password) {
try {
const user = await app.emailPasswordAuth.registerUser({ email, password });
return user;
} catch (error) {
console.error("Failed to register", error)
}
}
async function loginEmailPassword(email, password) {
// Create an email/password credential
const credentials = Realm.Credentials.emailPassword(email, password);
try {
// Authenticate the user
const user = await app.logIn(credentials);
// `App.currentUser` updates to match the logged in user
console.assert(user.id === app.currentUser.id);
return user;
} catch (error) {
console.error("Failed to log in", error);
}
}
While going through the mongodb class documentation, I wrote the following function which appears to work.
The code is checking for if their is any user in currentUser, if their is no currentUser, their no account logged in. In the event their is a currentUser, the code then checks using currentUser.isLoggedIn if that user is logged and at the end returns a boolean value.
async function isUserLoggedIn() {
try {
const userStatus = await app.currentUser;
if (userStatus == null) {
return false
} else {
const userStatus = await app.currentUser.isLoggedIn;
return userStatus
}
} catch (error) {
console.log("Failed to fetch user", error);
}
}
// Check if user is logged in
isUserLoggedIn().then((value) => {
console.log(value);
}).catch((error) => {
console.log(error);
});
Related
I need to get the jwtToken from the Auth.signUp. Is this possible if i enable autoSignIn:{enabled:true}?
const signUp = async () => {
await Auth.signUp({
username: email,
password,
attributes: {
email, // optional
name,
},
autoSignIn:{
enabled: true
}
})
.then((data) => {
console.log(data.user); //user.signInUserSession is null
})
.catch((err) => {
if (err.message) {
setInvalidMessage(err.message);
}
console.log(err);
});
await Auth.currentAuthenticatedUser()
.then(user =>{
console.log(user)
})
.catch(error => {
console.log(error) //"User is not authenticated"
})
};
I call I want the jwttoken from the userSession data for conditional rendering and I store the token in my router.js. The response object from Auth.signUp contains a CognitoUser which has a signInUserSession value but its's null.
EDIT: Tried to call Auth.currentAuthenticatedUser() after but yields an error that user is not authenticated. But when i restart my app, the user will be authenticated. I still cant authenticate user on the same app "instance"
import { Auth, Hub } from 'aws-amplify';
const listener = (data) => {
switch (data.payload.event) {
case 'autoSignIn':
console.log('auto sign in successful');
console.log(data.payload) //returns user data including session and tokens.
//other logic with user data
break;
}
};
Above is the code to initalize the Hub listener provided by amplify api. Ater user presses sign up, I called to get user session data when user is automatically signed in.
Hub.listen('auth', listener)
i have a react natve app it has a signup whith google button when i click on signin i am getting data in console.log i want to save the data in firebase i sont know how to do it
const googleLogin = async () => {
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
console.log(userInfo);// i am getting user data here
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// user cancelled the login flow
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (e.g. sign in) is in progress already
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
} else {
// some other error happened
}
}
};
You can refer to this LINK for google social auth, this is what you're looking for to save the auth data to firebase:
import auth from '#react-native-firebase/auth';
import { GoogleSignin } from '#react-native-google-signin/google-signin';
async function onGoogleButtonPress() {
// Check if your device supports Google Play
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true });
// Get the users ID token
const { idToken } = await GoogleSignin.signIn();
// Create a Google credential with the token
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
// Sign-in the user with the credential
return auth().signInWithCredential(googleCredential);
}
This can helpful. Just make sure you have integrated all libraries for firebase authentication.
import {
GoogleSignin,
statusCodes,
} from '#react-native-google-signin/google-signin';
import auth, {FirebaseAuthTypes} from '#react-native-firebase/auth';
// This function will be call on tapping sign in with google button
const signInWithGoogle = async () => {
try {
// This will check whether there is Google play service or not
await GoogleSignin.hasPlayServices();
//This will give you userInformation
const userInfo = await GoogleSignin.signIn();
// This will create new credential which can help to signIn in firebase
const credential = auth.GoogleAuthProvider.credential(userInfo.idToken);
//Here we are trying to return promise so when we call function we can have promise object
return new Promise((resolve, reject) => {
auth()
.signInWithCredential(credential)
.then(response => {
console.log('response in', response);
resolve(response);
})
.catch(error => {
console.log('error in', error);
reject(error);
});
});
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
// user cancelled the login flow
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (e.g. sign in) is in progress already
alert(JSON.stringify(error));
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
alert(JSON.stringify(error));
} else {
alert(error);
}
}
};
Now when you call this function on google button on press it will give you promise object and you can do it like below.
onPress={() => {
SignInMethods.signInWithGoogle()
.then(response => {
console.log('user information from firebase authentication', response.user);
})
.catch(error => {
console.log('error in google sign in :', error);
});
}}
I am trying to detect the userstate. If the user is logged in I want to set the data "userstate" to true. I am using vuefire and firebase into my vue project. I tried the way shown below, but it does not work
data() {
return {
userstate:false
};
},
watch:{
userstate:{
firebase.auth().onAuthStateChanged(function(user){
if(user){
this.userstate= true;}
else{
this.userstate=false;
}
})}
In Firebase you can check whether the user is signed in or not by using a function provided by the firebase which is auth().currentUser
// user will return true which means user EXISTS!
let user = firebase.auth().currentUser;
if (user) {
this.userstate = true; // If it exists
} else {
this.userstate = false; // If it doesn't
}
There are cases when the above mentioned method returns null / undefined for the user. So this solution is for your existing solution. So in that case try modifying your existing function to this:
async function IsLoggedIn() {
try {
await new Promise((resolve, reject) =>
firbase.auth().onAuthStateChanged(
user => {
if (user) {
// Yes User is signed in.
resolve('User is there');
} else {
// No user is not signed in.
reject('There is no user');
}
},
// Prevent console errors
error => reject(error)
)
)
return true
} catch (error) {
return false
}
}
Also since you intend to watch for the auth state change you can simply register the listener right after you initialize Firebase, you do not necessarily have to insert it in a VueJS watch block, you can insert it in your main.js for example, and if you are using a store like VueX you can update the state in the store and pull that information from any component of the VueX application.
firebase.initializeApp(configOptions);
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.userstate = true;
} else {
this.userstate = false;
}
});
I'm coding a "delete account" functionality on my app and I want the user to enter their password again before triggering the deletion.
What would be the best way to implement this? I was thinking on using the "signInWithEmailAndPassword" method and capturing the result to check if the credentials are correct, but I'm afraid that would overwrite the current session.
Any tips?
If the session is too old or whatever, an error is thrown by the 'delete account' function anyways. Then you need to re-auth the user. There is a special function for that too: reauthenticateWithCredential().
Here I have an example to show the difference of the login and re-authenticate functions (copied from a project of mine and cut down a bit because there was some analytics and stuff):
public async reAuthenticate(user: User, { email, password }: IEmailLoginData): Promise<UserCredential> {
const credentials = firebase.auth.EmailAuthProvider.credential(email, password);
return user.reauthenticateWithCredential(credentials)
.catch(e => {
console.error(e);
throw e;
});
}
public async login({ email, password }: IEmailLoginData): Promise<UserCredential> {
return firebase.auth().signInWithEmailAndPassword(email, password)
.catch(e => {
console.error(e);
throw e;
});
}
// PS: IEmailLoginData is a custom interface from me, but it just contains email and password
Also, here is the code for the 'delete account'. It should be pretty self-explanatory - hope it helps a bit:
async delete(): Promise<void> {
const dialogRef = this.dialog.open(YesNoDialogComponent, {
data: {
yes: 'Yes',
no: 'No',
title: 'Are you sure that you want to delete your account?'
}
});
const result = await dialogRef.afterClosed().pipe(take(1)).toPromise();
if (result === IYesNoDialogResult.YES) {
try {
const authUser = await this.auth.nextAuthUser(); // Getting the current firebase user from my custom service
await authUser.delete();
await this.router.navigateByUrl('login');
} catch(e) {
const toast = await this.toast.create({
duration: 3000,
message: 'This is a sensitive operation. Please login again to do this'
});
await toast.present();
await this.router.navigateByUrl('reauth');
});
}
}
For different auth provider it might be slightly different, but in the essence it is still the same. Just for example with google (if you want to use the Ionic Native Google Plus Login Plugin), you need to create the re-authenticate credentials from the plugin result:
public async reAuthenticate(user: User): Promise<UserCredential> {
try {
if (this.platform.is('cordova')) {
try {
const gUser = await this.gPlus.login({
webClientId: environment.googleWebClientId,
offline: true,
scopes: 'profile email'
});
const credential = firebase.auth.GoogleAuthProvider.credential(gUser.idToken);
return await user.reauthenticateWithCredential(credential);
} catch (nativeE) { // If login failed via native method, fallback to redirects
if (nativeE == 12501 || nativeE == 13) { // User cancelled login
return null;
}
console.error(nativeE);
// In constructor:
// this._provider = new firebase.auth.GoogleAuthProvider();
await user.reauthenticateWithRedirect(this._provider);
return await firebase.auth().getRedirectResult();
}
}
else {
return await user.reauthenticateWithPopup(this._provider);
}
} catch (e) {
console.error(e);
throw e;
}
}
I have an app using sign in with a custom token, written on webpack observes. What I want to do now is mark the user after successful login by custom token as logged on firebase auth and firebase firestore, where I have the collections with users, and document for each user with data and some uid. I don't know how to to that.
Here is my code:
generateToken(uid) {
const uid = 'some-uid';
this.trigger(this.signals.action.onGenerateToken);
firebase.admin.auth().createCustomToken(uid)
.then((customToken) => {
console.log(customToken);
})
.catch(function (error){
if (error.Code === 'auth/invalid-custom-token') {
alert('The token you provided is not valid.');
}
else {
this.trigger(this.signals.error.onGenerateToken);
}
})
}
login(uid) {
firebase.auth().signInWithCustomToken(token)
.then(function() {
var user = firebase.auth().currentUser;
if (user) {
//mark the user as active (logged) after successful login on firebase auth and firebase firestore
};
this.trigger(this.signals.success.onLogin);
})
.catch(function(error) {
if (errorCode === 'auth/too-many-requests') {
this.trigger(this.signals.error.tooManyRequests);
}
else {
this.trigger(this.signals.error.userDisabled);
}
});
}
If I understand your question correctly, first create a reference to your user document, then call update() on the reference and pass in an object containing the properties you want to update and their new values.
let userRef = firebase.database().ref('users/' + userId);
userRef.update({active:true});
Check the firebase docs for more info on how to read and write to firebase.