This user is not allowed to query email on class _User

I am using Sign In With Apple and Email/passsword based login for which below are truncated code snippets.

In Apple signing in, i am getting error “This user is not allowed to query email on class _User” when i try to query on PFUser whether a user with the associated email is already registered.
Same query under email based method doesn’t fail.

What could be the reason?

 func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        switch authorization.credential {
            
            case let credentials as ASAuthorizationAppleIDCredential:
                                    
                    let appleCredentialUserId = credentials.user //use as social_id

                    //check whether _User with this id already exits, if so login with it.
                    //MARK : this query works
                    CommonHelper.findSocialUser(for: appleCredentialUserId) { (user, error) in

                        if error == nil && user != nil {
                            //MARK: Login existing Apple user
                            //Account exists with Apple auth and this social id so login to parse
                            let authData = ["token":idTokenString!, "id": appleCredentialUserId]
                                                       
                            self.loginWith(authType: "apple", using: authData) { (loggedInUser, error) in
                                    //Post login view
                                } else if error != nil {

                            } //self.loginWith(authType: "apple",       
                        } else if error == nil && user == nil {
                                                        
                            let queryToCheckEmailTaken = PFUser.query()
                            queryToCheckEmailTaken?.whereKey("email", equalTo: credentials.email!)

                            //search if account already exists with selected email id.
                            //if doesnt exist then perform registration else login
                            //MARK: This fails
                            queryToCheckEmailTaken?.findObjectsInBackground(block: { (objects, error) in                            
                            
                        } else if error != nil {
                                CommonHelper.showMessage(messageBody: "Could not login. Please try again.")
                            }
                        } 
                    }
                    
                break
    }
    

func loginWithEmail(_ sender: Any) {
                                    
        // check whether account with same email exists
        // if yes then error else login
        
        let query = PFUser.query()
        query?.whereKey("email", equalTo: emailToLoginWith)
        query?.whereKey("login_provider", notEqualTo: "email")
                    
        //MARk: This works
        query?.getFirstObjectInBackground(block: { (user, error) in
            
            if error == nil && user != nil {
                CommonHelper.showMessage(messageBody: "This mail is already being used by another user.",)
            } else {

                // go ahead with login
                PFUser.logInWithUsername(inBackground: emailToLoginWith, password: self.passwordTextField.text!) {
                        (user, error) in

                }
             
            } 
        })       
}
1 Like

Querying users by email is restricted for security reasons. Easiest solution is to create a CloudCode function which checks whether an account exists. There you can use a query with masterKey: true to find the user by email.

1 Like

I am aware but same query works in another instance. Pls see the code example.

Haven’t tried this myself, but I assume that the 2nd query works bc it queries a single object (getFirstObjectInBackground), while the 1st one queries multiple objects (findObjectsInBackground – even though it would only return a single object in your case). So you could try to use getFirstObjectInBackground instead of findObjectsInBackground.

I also tried changing to getFirstObjectInBackground and countObjectsInBackground but getting same error.

By the way, the query works in my local environment which is same as test environment but runs on DigitalOcean App platform. And this code was working earlier when i had deployed on Heroku.

@dr_barto Thanks fie the direction. I implemented cloud code finally.

1 Like

can you share how you did this ?

I assume you are aware of how to create cloud code and calling from client code. You may follow Parse Server and relevant client guide.

Hope this helps.

Parse.Cloud.define(“checkEmailAlreadyRegisteredForAppleSignup”,async (request) => {
var emailId = request.params.emailId;
var userId = request.params.userId ;

var userQuery = new Parse.Query(‘_User’);
userQuery.equalTo(‘email’, emailId);
userQuery.notEqualTo(‘user_id’,userId)

try {
var count = await userQuery.count({ useMasterKey: true });

return count //return count of no of rows 

} catch (error) {

throw error

}
});