Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix firebase "User is not authorized" error even though user is authenticated in registration flow?

Im trying to do a variety of firebase actions in one call in a react-native app using react-native-firebase. the flow goes something like this:

  • create user in authentication
  • send image to storage
  • send data to firestore

During the image-storage phase, the imgRef.putFile() function errors out saying the user isn't authorized. However im using createUserWithEmailAndPassword() (which authenticates a user in on completion) and then using the returned credential to do the rest of the work, image storage and firestore creations.

firebase storage rules are set to allow only authenticated users. here's the ruleset:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Also, I have enabled anonymous signin in authentication methods.

here's the initial action up until the error point:

return (dispatch) => {
        dispatch({ type: types.REGISTER_USER });
        console.log('starting registration process...');
        firebase
            .firestore()
            .collection('users')
            .where('username', '==', username)
            .get()
            .then((querySnapshot) => {
                console.log(querySnapshot);
                if (querySnapshot.empty !== true) {
                    registrationFail(dispatch, 'Username already taken. Try again.');
                    console.log("Registrant's username already exists");
                } else {
                    console.log('Registrants username is unique');
                    firebase
                        .auth()
                        .createUserWithEmailAndPassword(email, pass)
                        .then((userCredential) => {
                            uploadImg(dispatch, img, userCredential.user.uid)

here's the uploadImg() function:

const uploadImg = async (dispatch, uri, uid) => {
    console.log('Starting image upload...');
    dispatch({ type: types.UPLOAD_IMG, info: 'Uploading profile image...' });
    const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri;
    const imgRef = firebase.storage().ref('profile-images').child(uid);
    return imgRef
        .putFile(uploadUri, { contentType: 'image/png' })
        .then((success) => {
            console.log('profile image upload successful.')
            return imgRef;
        })
        .catch((err) => {
            console.log('profile image upload failed: ' + err)
            uploadImgFail(dispatch, err.message);
        });
};

again, the error that logs in the console is:

profile image upload failed: Error: User is not authorized to perform the desired action.

logging the firebase.auth().currentUser right before the uploading() function returns the current user object successfully.

this security rule issue also happens with Firestore, despite my security ruleset for the given collection being:

match /databases/{database}/documents {
    match /users/{uid} {
      // allow new user to check phone numbers
      allow read: if true
      allow update, create: if request.auth != null 
      allow delete: if request.auth.uid == uid
    }
 }

This is a part of my registration flow. I collect input, send relevant data to redux action, create a user, once the user is created, I add some data to a document in firestore. this makes no sense. im referencing the documentation and it still doesn't work.

How can this be fixed?

like image 952
Jim Avatar asked Aug 25 '20 21:08

Jim


1 Answers

It seems to be an issue with firebase that you have to logout() the user once before you can log in after user creation. I faced the same issue and this is my workaround:

     firebase.auth().signInWithEmailAndPassword(userEmail,userPass).catch((error) => {
                /*console.log('Could not log in user');*/
                console.log(error);
                firebase.auth().createUserWithEmailAndPassword(userEmail,userPass).catch((error) => {
                    /*console.log('Could not create user');*/
                    console.log(error);
                }).then(result => {
                        firebase.auth().signOut().then(() => {
                            firebase.auth().signInWithEmailAndPassword(userEmail,userPass).then(result => {
                                /*console.log("here is you logged in user");*/
                            })
                        });
                    });
                });
            });
like image 122
Lukas Avatar answered Oct 13 '22 07:10

Lukas