I'm getting undefined ID after using createUserWithEmailAndPassword function.
Here is the code:
return async (dispatch) => {
dispatch({ type: ATTEMPTING });
if(name && email && password)
{
try {
await firebase.auth().createUserWithEmailAndPassword(email, password)
.then(user => handleAccountCreated(dispatch, user.uid, name,email,radio))
.catch(error => handleError(dispatch, error.message));
}catch(e) {
handleError(dispatch, e.message);
}
}else{
handleError(dispatch, "There is an error in your data");
}
}
const handleAccountCreated = (dispatch, userId, name,email , radio) => {
const ip = '223';
firebase.database().ref(`mydatabase/${userId}`)
.set({ name ,email,ip,radio})
.then(() => { dispatch({ type: SIGNUP_SUCCESS }); })
.catch(error => handleError(dispatch, error.message));
}
I have already tried with :
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(firebase.auth().onAuthStateChanged( user => handleAccountCreated(dispatch, user.uid, name, email ,radio)))
the same issue
Related
I am trying to develop a react-native-app but everything was good. Once I have changed the authentication rules in firebase real time database. From that time, I am not able to POST/GET any request from firebase. I am storing the idToken which is returned after a user sign in the application in redux store.
case actionTypes.AUTHENTICATE_USER:
return {
...state,
isAuth: true,
token: action.payload
}
export const authUser = token => {
return {
type: actionTypes.AUTHENTICATE_USER,
payload: token
}}
The Login action code is as follows:
export const tryLogin = (email, password, navigate) => dispatch => {
fetch("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + API_KEY, {
method: "POST",
body: JSON.stringify({
email: email, password: password, returnSecuretoken: true
}),
headers: {
"Content-Type": "application/json"
}
})
.catch(err => {
console.log(err);
alert("Authentication Failed");
})
.then(res => res.json())
.then(data => {
if (data.error) {
alert(data.error.message);
}
else {
dispatch(authUser(data.idToken));
navigate("Home");
}
console.log(data);
})}
And I get the error while running the following code:
export const addPlace = place => (dispatch, getState) => {
let token = getState().token;
console.log("Add place Token:", token);
fetch(`https://first-react-native-proje-7df03-default-rtdb.asia-southeast1.firebasedatabase.app/places.json?auth=${token}`, {
method: "POST", body: JSON.stringify(place)
})
.catch(error => console.log(error))
.then(response => response.json())
.then(data => console.log("Dispatch Error", data))}
export const loadPlaces = () => (dispatch, getState) => {
let token = getState().token;
fetch(`https://first-react-native-proje-7df03-default-rtdb.asia-southeast1.firebasedatabase.app/places.json?auth=${token}`)
.catch(err => {
alert("Something Went Wrong, Sorry!");
console.log(err);
})
.then(res => res.json())
.then(data => {
const places = [];
for (let key in data) {
places.push({
...data[key],
key: key
})
}
dispatch(setPlaces(places));
})}
My firebase rule is as follows as I am still in initial phase:
{"rules": {
".read": "auth!=null" , // 2022-8-4
".write": "auth!=null", // 2022-8-4
}}
I am not getting any way to solve this. Please help.
Solved. The problem was with the returnSecureToken:true. I wrote returnSecuretoken which was creating the error. It will be:
export const tryLogin = (email, password, navigate) => dispatch => {
fetch("https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=" + API_KEY, {
method: "POST",
body: JSON.stringify({
email: email, password: password, ***returnSecureToken: true***
}),
headers: {
"Content-Type": "application/json"
}
})
.catch(err => {
console.log(err);
alert("Authentication Failed");
})
.then(res => res.json())
.then(data => {
if (data.error) {
alert(data.error.message);
}
else {
dispatch(authUser(data.idToken));
navigate("Home");
}
console.log(data);
})
}
I have login code in react native using firebase and google signin auth.
So when new user sign in using google account, I set new data. And if user has signed in before, user go to main page.
My problem is when new user sign in > code start to get signInWithCredential > set new data user, before set data finish, onAuthStateChanged was detect there is change in auth and start to get user document / data. But because it's not finish yet, it throw error 'Can Not Get UID / Undefined UID'.
This is my login page code:
const _signIn = async () => {
setInitializing(true);
try {
await GoogleSignin.hasPlayServices();
const userInfo = await GoogleSignin.signIn();
const credential = auth.GoogleAuthProvider.credential(
userInfo.idToken,
userInfo.accessToken,
);
await auth()
.signInWithCredential(credential)
.then(response => {
const uid = response.user.uid;
const data = {
uid: uid,
email: userInfo.user.email,
fullname: userInfo.user.name,
bio: 'Halo!! ..',
username: uid.substring(0, 8),
};
const usersRef = firestore().collection('users');
usersRef
.doc(uid)
.get()
.then(firestoreDocument => {
if (!firestoreDocument.exists) {
usersRef
.doc(data.uid)
.set(data)
.then(() => {
setInitializing(false); return;
})
.catch(error => {
setInitializing(false);
Alert.alert(JSON.stringify(error.message));
});
} else {
setInitializing(false);
return;
}
})
.catch(error => {
Alert.alert(JSON.stringify(error.message));
console.log('Error getting document:', error);
return;
});
});
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
setInitializing(false);
Alert.alert('Sign in canceled');
} else if (error.code === statusCodes.IN_PROGRESS) {
setInitializing(false);
Alert.alert('Signin in progress');
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
setInitializing(false);
Alert.alert('PLAY_SERVICES_NOT_AVAILABLE');
} else {
setInitializing(false);
Alert.alert(JSON.stringify(error.message));
}
}};
And this is my index page code to check auth user:
useEffect(() => {
try {
NetInfo.fetch().then(state => {
if(state.isConnected === false){
Alert.alert('No Internet Connection Detected');
setInitializing(false);
return;
}
});
setInitializing(true);
await auth().onAuthStateChanged(user => {
if (user) {
const usersRef = firestore().collection('users');
usersRef
.doc(user.uid)
.get()
.then(document => {
const userData = document.data().uid;
setisLogin(userData);
})
.then(() => {
setInitializing(false);
})
.catch(error => {
setInitializing(false);
Alert.alert(JSON.stringify(error.message));
});
} else {
setInitializing(false);
}
});
} catch (error) {
Alert.alert(error);
} }, []);
How to wait auth().signInWithCredential finish? Thankyou.
If you need to perform more actions such read data from database or so after the user logs in, you should ideally unsubscribe from onAuthStateChanged. Essentially it won't trigger when the auth state changes (i.e. user logs in) and let you do your own custom actions. Once your processing is done, then you manually redirect the user to where the onAuthStateChange would have redirected is the user wa s logged in.
const authStateListenter = await auth().onAuthStateChanged(user => {
//...
})
// Unsubscribe auth state observer when _signIn function runs
const _signIn = async () => {
setInitializing(true);
authStateListenter()
}
Calling authStateListener will disable the auth state observer. It's similar to detaching Firestore's listeners.
For some reason this code fail to sign up on firebase,
app.post('/signup', (req, res) => {
const newUser = {
email: req.body.email,
password: req.body.password,
confirmPassword: req.body.confirmPassword,
handle: req.body.handle
}
let token, userId;
db.doc(`/users/${newUser.handle}`).get().then(doc => {
if (doc.exists) {
return res.status(400).json({ handle: 'this handle already exists' })
} else {
return firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password)
}
})
.then(data => {
userId = data.user.uid;
return data.user.getIdToken();
})
.then(idToken => {
token = idToken;
const userCredentials = {
handle: newUser.handle,
email: newUser.email,
createdAt: new date().toISOString(),
userId
}
return db.doc(`/users/${newUser.handle}`).set(userCredentials)
})
.then(() => {
return res.status(201).json({ token });
})
.catch(err => {
if (err.code === "auth/email-already-in-use") {
return res.status(400).json({ email: 'Email is alrready in use' })
} else {
return res.status(500).json({ general: 'something went wrong, please try again' })
}
})
});
I always get { general: 'something went wrong, please try again' } , i am using postman to mimic the request to firebase,
This code works perfectly:
firebase.auth().createUserWithEmailAndPassword(newUser.email, newUser.password)
.then(data => {
return data.user.getIdToken();
})
.then(token => {
return res.status(201).json({token})
})
.catch(err => {
console.error(err);
return res.status(500).json({error: 'something went wrongly'})
})
The first trial is from a tutorial i am following in Youtube and sadly it doesn't work
On the backend, you can use Firebase Admin SDK to get details about any user but it does not have any ability to login on behalf of user.
In a react-native application, dispatching an action that invokes firebase-auth to sign-out ends in a firebase permission error:
Here's the method inside the drawer component that dispatches the action:
logout = () => {
this.props
.logoutUser()
.then(() => {
this.props.navigation.navigate('Login');
})
.catch((err) => alert(err));
};
and here's the logout action:
export const logoutUser = () => {
return (dispatch) => {
return new Promise((resolve, reject) => {
firebase
.auth()
.signOut()
.then(() => {
dispatch({ type: types.RESET_APP });
console.log('Dispatching types.RESET_APP');
resolve();
})
.catch((error) => reject(error.message));
});
};
};
When executed, the screen reverts back to the login screen as desired. Console logs Dispatching types.RESET_APP, and THEN the error above displays.
authStateChanged Listener in my login:
export const loginUser = (email, password) => {
return (dispatch) => {
dispatch({ type: types.LOGIN_USER });
// listen for change in auth state before signing in
return new Promise((resolve, reject) => {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((userCredential) => {
console.log('User Credential: ' + JSON.stringify(userCredential));
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
if (user) {
console.log('Logged in: ' + user.email);
loginUserSuccess(dispatch, user);
resolve(user);
} else {
console.log('Authentication state changed, user object is null...');
//resetAuth();
}
});
// No longer need to listen to auth state
unsubscribe();
})
.catch((error) => {
console.log('Error during Email sign-in: ' + error);
loginUserFail(dispatch, error.message);
});
});
};
};
auth state observer is unsubscribed in the login function, so whats causing this?
Before iOS 11.3 my app is working fine, but after the ios 11.3 was released new users from facebook cannot login to my app. But exisiting users still can login via facebook using their fb accounts.
im new too React native can please anyone help me. this is my facebook login code:
export const fbLogin = () => async dispatch => {
dispatch({ type: LOADING_TRUE });
LoginManager.logInWithReadPermissions([
'public_profile',
'user_birthday',
'email',
'user_photos'
]).then(
result => {
if (result.isCancelled) {
console.log('cancelled');
dispatch({ type: ERROR_HANDLER });
} else {
AccessToken.getCurrentAccessToken().then(data => {
const token = data.accessToken;
fetch(
'https://graph.facebook.com/v2.8/me?fields=id,name,email,gender,birthday&access_token=' +
token
)
.then(response => response.json())
.then(json => {
let userData = json;
let id = userData.id;
const fbProfilePic = `https://graph.facebook.com/${id}/picture?height=150`;
dispatch({
type: GET_PROFILE_PICTURE,
payload: fbProfilePic
});
const credential = firebase.auth.FacebookAuthProvider.credential(
token
);
firebase
.auth()
.signInWithCredential(credential)
.then(user => {
console.log('firebase facebook login!');
let currentUser = firebase.auth().currentUser;
if (currentUser !== null) {
const name = currentUser.displayName;
const email = currentUser.email;
const uid = currentUser.uid;
const birthday = json.birthday;
const gender =
json.gender === Languages.common.male_en
? Languages.common.male
: Languages.common.female;
userData.gender = gender;
let userDetails;
const db = firebase.firestore();
const docRef = db.collection('users').doc(uid);
docRef
.get()
.then(doc => {
if (doc.exists) {
// more than 2 times login
dispatch({
type: GET_USER_DATA,
payload: doc.data()
});
} else {
// first log in
const dateCreated = Moment()
.format('YYYY-MM-DD hh:mm:ss')
.toString();
userDetails = docRef.set({
name,
email,
birthday,
gender,
dateCreated,
uri: fbProfilePic
});
dispatch({
type: GET_USER_DATA,
payload: userData
});
}
})
.catch(error => {
dispatch({
type: ERROR_HANDLER,
payload: error
});
});
Actions.checkInHistory();
}
})
.catch(error => {
dispatch({
type: ERROR_HANDLER,
payload: `Error: ${error}`
});
});
})
.catch(err => {
dispatch({
type: ERROR_HANDLER,
payload: err
});
});
});
}
},
error => {
dispatch({
type: ERROR_HANDLER,
payload: error
});
}
);
};
Then this error is appearing:
this error is coming from my last error handler
I dont know what happened but when I put LoginManager.logOut() before the LoginManager.logInWithReadPermissions() new facebook users can now login to my app.