Login redirect

Debugging backend code is tricky because you often can’t see what is going on in the backend. First things first. Does the code run in preview mode?

I often will use console_log messages, especially in the frontend to see what is going on. When in preview mode, you can see these message printout on your debug console. For example in your front end code, you can check what was returned from the await function call.

let found = await checkUserEmail( email );
console_log("[module-name:onReady()] - "+"The found variable contains: "+ found);

This can help you see what is coming back from the backend. The backend is harder to see what is going on.

I’ve had to create my own debug system to monitor what is going on in the backend. In short, I save status messages into a collection, as things are running in the backend. I let the code run, then look at the collection to review the messages to see what transpired in the backend. It is not a perfect system, but in order to let this work with minimal extra stuff, I found this the simplest way.

I did test the backend code, and it was working properly (I did debug it). I wonder if there is some page security or table security causing grief.

Did you look at the hasLoggedIn table to see if there are any entries? As well, did you manually try and enter a record into the collection, (eg your email) and test it and see what found tells you.

As well for the button code, try some console_log lines to see what is going on.
eg:
export somebutton_click(event) {
console_log(“I just entered the button click event.”);
if (wixUsers.currentUser.loggedIn) {
// log the user out
console_log(“Wix reported that the user IS logged in.”);
wixUsers.logout();
wixLocation.to (‘/’);
} else {
console_log(“Wix reported that the user IS NOT logged in.”);
}
}

Sometime, instead of using a console_log, I will temporarily put on the page a textbox that I can see. I will set the message of the textbox, to the debugging messages, so I can see on the page what is going on.

@pekrzyz This is the what I get when I run the jsw code

There was no data added to the dataset, I tried manual addition of my email but it still didn’t work

Great, that’s some progress. What the message is saying that you are passing to the function a null, instead of the email. In the front end do a console log of the email variable before calling the await. Also, you can test it manually, as well by setting the email value with something valid.
EG:, before the call to checkUserEmail,
email = “myemailtotest”;

@pekrzyz So Sorry but didn’t understand what you said. I have very basic coding knowledge almost none in this case. Please try to make it simple or leave a link to refer.

Also I cross checked the entire code once its the only error in the backend and nothing else so far

console_log("Email is set to: " + email);
let found = await checkUserEmail( email );

See what you get when the console_log print out.

You do understand that you can not run the code in the .jsw directly. It needs a parameter passed to it in order to run. It is expecting the email variable. That is why it has to be called by the frontend. The frontend is getting the email, and then passing that value into the function.

Yes I understand that, but that still doesn’t help as I can’t figure the proper coding part since I lack the coding knowledge.

Is there a easier way to this? As I think it’ll take me a long time to get it to work properly since I don’t know anything about backend coding and linking it with frontend

You may need to get further help to understand the code.

What I can tell you is:
The backend code lives in the backend folder called: checkRegistered.jsw

The frontend code lives on your web page. The page that is going to use the backend code.

The front end code needs the import line, which identifies what the backend function name is, and what module in the backend it lives in.

The line is: import {checkUserEmail} from ‘backend/checkRegistered’;

This line tells the front end, there is a fuction called ‘checkUserEmal’ and it lives in the backend in, ‘backend/checkRegistered’.

This is enough information, so the frontend code (on your webpage), now can connect to the backend function and run it.

The frontend calls the backend to check the found status.
The line is: let found = await checkUserEmail( email );

This line is where the front end calls the backend function. It also passes to it the email address it retrieved from the wixUser api.

The following lines in your frontend code, fetched the email address and passed it in to the backend code.

// call the wixUsers api, call the onLogin() method, get info on user logged in
wixUsers.onLogin((user)=>{
//get the email object from the user logged in
user.getEmail()
// get the email address from the user object
.then ( (email) => {
// take the email address and test if logged in before
// using the backend code: checkUserEmail
let found = await checkUserEmail( email );

Hi, did some reading on both frontend and backend coding. I have one question, Don’t we need an onclick event function in the frontend code. The front end clod that you gave doesn’t have the onclick function, so how will the login button work or does the front end code you provided not need a onclick function to trigger the login button?

Yes, absolutely. In order to run the code you have to have something call it. For example, you may have a ‘Login’ button. This button would need an onClick() event added to it, so that you can have it run code after the user clicks on it. From that onClick() event, you would call the frontend function, to test your user’s email stuff.

I could not provide the code for the onClick() event, because I don’t know the structure of your website. I don’t know the names of your button(s) etc.

I am only using one button, i.e. login button with id as logNow and other two fields i.e. email (loginEmail) and password (loginPassword). Can you please modify the code to include the onclick function.

I have given login code that I modified according to my needs hope its helps to understand the structure of site,

import wixUsers from ‘wix-users’ ;
import wixLocation from ‘wix-location’ ;
import { checkUserEmail } from ‘backend/checkRegistered’ ;

$w . onReady ( async function () {

wixUsers . onLogin (( user )=>{ 

    user . getEmail () 

    . then  ( ( email ) => { 
     $w . onReady ( **async function**  () { 

        **let**  found  =  **await**  checkUserEmail (  email  ); 


        **if**  ( ! found  ) {  

            // user is new, never logged in before 

            wixLocation . to ( "/registration-moreinfo" );  

        }  **else**  { 

            // user was found, previously logged in 

            user . getRoles  () 

            . then (( roles ) =>{ 

                **let**  role  =  roles  [ 0 ] 

                **let**  roleName  =  role . name  

                **if**  ( roleName  === "Parents" ) { 

                    wixLocation . to ( "/parent-profile/" );  

                }  **else if**  ( roleName  ===  "Class XI & XII - Applied Mathematics" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XI - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XII - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XII - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XI - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 
                } 



            }) 

        } 
     }) 

    }) 

}) 

})

Thanks

I can’t do that, because only you can do that from the developer tab. Click on your logNow button to select it in developer mode. Make sure you have Dev mode enabled. This will bring up at the bottom right) a set of choices. You should see the Event Handlers section. Click on the onCLick event. It will create the onClick_event function and give it a name, which you will see to the right. Then click on the name of the event, and it will open up the function, where you can edit it and add your code.

I have shown you an example of a button I have a Booking button called buttonBook and I added an onClick_event to it. The image shows what you should see in the bottom right.

Thanks man, it works perfectly. Though right now we can bypass the profile creation if we just refresh the page after our first login without actually creating a profile. As in since the first login happened the code will redirect the person to the other pages from second login onwards without actually checking if the profile was created or not. Is a fix for that?

import wixUsers from ‘wix-users’ ;
import wixLocation from ‘wix-location’ ;
import { checkUserEmail } from ‘backend/checkRegistered’ ;

export function loginNow ( event ) {
// This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
// Add your code for this event here:
let emaail = $w ( “#loginEmail” ). value
let password = $w ( “#loginPassword” ). value
wixUsers . login ( emaail , password )
. then (() => {
console . log ( “user logged in” )
})
. catch (( err ) => {
console . log ( err )
})
}

$w . onReady ( async function () {

wixUsers . onLogin (( user )=>{ 

    user . getEmail () 

    . then  ( ( email ) => { 
     $w . onReady ( **async function**  () { 

        **let**  found  =  **await**  checkUserEmail (  email  ); 


        **if**  ( ! found  ) {  

            // user is new, never logged in before 

            wixLocation . to ( "/registration-moreinfo" );  

        }  **else**  { 

            // user was found, previously logged in 

            user . getRoles  () 

            . then (( roles ) =>{ 

                **let**  role  =  roles  [ 0 ] 

                **let**  roleName  =  role . name  

                **if**  ( roleName  === "Parents" ) { 

                    wixLocation . to ( "/parent-profile/" );  

                }  **else if**  ( roleName  ===  "Class XI & XII - Applied Mathematics" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XI - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XII - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XII - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XI - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 
                } 



            }) 

        } 
     }) 

    }) 

})
})

Question: When you process the new user for the first time, "registration-moreinfo’, do you save the details about that user’s info somewhere? In a table? (I’m calling this first step).

If so, you can add a check on the second part of the code, where you direct the user based on their role, to see if that data has been saved from (first step). If the data is not there, then bump the user back to process the moreinfo stuff.

You have a model (checkUserEmail) that you can build from. Just create a new fuction called (checkForProfile) for example. You need to look further as to what is happening in the first step.

Yes I save it a data set which is linked to a dynamic profile creation page.
I tried doing the same thing you explained for the login by keeping the data set in the backend. I created two jsw files, “parentProfile” and “studentProfile”

The back end code for parentProfile and studentProfile checks for the first input in the dyanmic dataset i.e. firstName and also checks for a boolean field named “profileCreated” if its true then profile was created

Code for parentProfile jsw
import wixData from ‘wix-data’ ;

export async function checkForProfile ( firstName ) {

// convert email to uppercase, remove all spaces 
**let**  scrubbedFirstName  =  firstName . toUpperCase (). split ( " " ). join ( "" ); 


**let**  options  = { 
    "suppressAuth" :  **true** , 
    "suppressHooks" :  **true** 
}; 


**return**  wixData . query ( "Parent_profile" ) 
    . eq ( "firstName" ,  scrubbedFirstName ) 
    . find (  options  ) 
    . then ( ( results ) => { 
        **if**  ( results . items . length  ==  0 ) { 
        // didn't find email in table so save it 
            **let**  toInsert  = { 
                "firstName" :  scrubbedFirstName , 
                "profileCreated" :  **true** 
            } 
            wixData . insert ( "submit" ,  toInsert ,  options ) 
            **return**  **false** ; 
        }  **else**  { 
    //found email 
            **return**  **true** ; 
        } 
    }) 
    . **catch** ( ( error ) => { 
        console . log ( "[parentProfile:]\n"  +  error . message ); 
    }) 

}

code for studentProfile;
import wixData from ‘wix-data’ ;

export async function checkForProfile ( firstName ) {

// convert email to uppercase, remove all spaces 
**let**  scrubbedFirstName  =  firstName . toUpperCase (). split ( " " ). join ( "" ); 


**let**  options  = { 
    "suppressAuth" :  **true** , 
    "suppressHooks" :  **true** 
}; 


**return**  wixData . query ( "Student_profile" ) 
    . eq ( "firstName" ,  scrubbedFirstName ) 
    . find (  options  ) 
    . then ( ( results ) => { 
        **if**  ( results . items . length  ==  0 ) { 
        // didn't find email in table so save it 
            **let**  toInsert  = { 
                "firstName" :  scrubbedFirstName , 
                "profileCreated" :  **true** 
            } 
            wixData . insert ( "submit" ,  toInsert ,  options ) 
            **return**  **false** ; 
        }  **else**  { 
    //found email 
            **return**  **true** ; 
        } 
    }) 
    . **catch** ( ( error ) => { 
        console . log ( "[studentProfile:]\n"  +  error . message ); 
    }) 

}

I also modified my login front end this way by addding
import { checkForProfile } from ‘backend/parentProfile’ ; ‘backend/studentProfile’ ;

frontend code;
import wixUsers from ‘wix-users’ ;
import wixLocation from ‘wix-location’ ;
import { checkUserEmail } from ‘backend/checkRegistered’ ;
import { checkForProfile } from ‘backend/parentProfile’ ; ‘backend/studentProfile’ ;

export function loginNow ( event ) {
// This function was added from the Properties & Events panel. To learn more, visit Velo: Working with the Properties & Events Panel | Help Center | Wix.com
// Add your code for this event here:
let emaail = $w ( “#loginEmail” ). value
let password = $w ( “#loginPassword” ). value
wixUsers . login ( emaail , password )
. then (() => {
console . log ( “user logged in” )
})
. catch (( err ) => {
console . log ( err )
})
}

$w . onReady ( async function () {

wixUsers . onLogin (( user )=>{ 

    user . getEmail () 

    . then  ( ( email ) => { 
     $w . onReady ( **async function**  () { 

        **let**  found  =  **await**  checkUserEmail (  email  ); 
    
        **if**  ( ! found  ) {  

            // user is new, never logged in before 

            wixLocation . to ( "/registration-moreinfo" );  

        }  **else**  { 

            // user was found, previously logged in 
            **let**  found  =  **await**  checkForProfile (  email  ); 

            user . getRoles  () 

            . then (( roles ) =>{ 

                **let**  role  =  roles  [ 0 ] 

                **let**  roleName  =  role . name  

                **if**  ( roleName  === "Parents" ) { 

                    wixLocation . to ( "/parent-profile/" );  

                }  **else if**  ( roleName  ===  "Class XI & XII - Applied Mathematics" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XI - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Mathematics - Class XII - JEE" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XII - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 

                } **else if**  ( roleName  ===  "Chemistry - Class XI - JEE/NEET" ) { 

                    wixLocation . to ( "/student-profile/" ); 
                } 



            }) 

        } 
     }) 

    }) 

})
})

Is all of this correct?? please check

Again thanks for helping me and I am also learning from your explanations

Your becoming a Coding master!!!. I quickly reviewed your stuff and it looks darn good. I think it will run!!! If you want, you can actually put multiple functions into the same .jsw file.

import { checkUserEmail } from backend/checkRegistered’ ;
import { checkForProfile } from ‘backend/parentProfile’ ; ‘backend/studentProfile’ ;

I’m not sure the second import line will work, I think the javascript interpreter would get confused. You can put multiple functions into the same .jsw file, just give each function a unique name.

eg: import{checkParentProfile, checkStudentProfile} from ‘backend/checkProfiles’;

Put both of the checks into one .jsw file (eg checkProfiles.jsw).
I’ve had dozens of functions in a single backend file, and I just put them all in one import line, because they are all in a single .jsw file.

Thanks!!!

Everything worked out like a charm.

Planning to create a custom forgot password link, I read that as of now wix doesn’t support custom ones but we can create a “forgot password” text and link it to wix default forgot password using this code snip

$w(‘#forgotPasswordButton’).onClick( function () { wixUsers.promptForgotPassword(); })

but this send a reset password link that takes people to wix default login and not the custom login I created

is there any other way you are aware about?

@sunilsangam94 I have not worked with logins and password resets. You have to be very careful when dealing with password resets and users.

The problem is if you don’t do it right, than a hacker can change the password.

By Wix (as well as most other sites) sending the challenge/response via an email, hopefully the person’s email hasn’t been hijacked, and will get an alert that the password change has been requested. If the user responds to the email and clicks through to reset the password, then Wix knows that the user whose email is registered with the ID requested the password change.

If someone is trying to change the password and shouldn’t be, then the user is also alerted that someone else is trying to change the password.

This is one place you want to tread very carefully. If you screw it up, it could be hazardous to your website.

@pekrzyz OK I understand, I’ll try get help from the wix support team for this matter then.

Can we make a error catch such that if a non existing member tries to login to the site an error message of “become a member or register first” pops up? I have already placed a error code for wrong password or emails but not for a non existing member logins