Prevent event from firing more than once for AWS Amplify

I have a tricky situation due to a strange behavior of AWS Amplify library. When I subscribe to it’s Auth event, and the user logs in, the event fires 4-6 times, and so my backend get’s hit multiple times as well, this is inefficient and I want it to stop after one success. Here is my code:

useEffect(() => {
        const authListenerCancelToken = Hub.listen("auth", ({ payload: { event, data }}) => {
            switch (event) {
                case 'signIn':
                case 'cognitoHostedUI':
                    getUserAndProcess(authListenerCancelToken)
                        .catch(console.error);
                    break;
                case "signOut":
                    setUser(null);
                    break;
                case 'signIn_failure':
                case 'cognitoHostedUI_failure':
                    console.log('Sign in failure', data);
                    break;
            }
        });

        getUserAndProcess(authListenerCancelToken).catch(console.error);
    }, []);

const getUserAndProcess = async (eventCancelToken: () => void) => {
        try {
            console.log("processing user...");
            const currentUser = await Auth.currentAuthenticatedUser() as CognitoUser
            if(currentUser != null) eventCancelToken(); //stop listening to any more auth events, but clearly not working, maybe gets called very rapidly multiple times?
            setUser(currentUser);

            const userSession = currentUser.getSignInUserSession();
            const idToken = userSession?.getIdToken().getJwtToken();
            const accessToken = userSession?.getAccessToken().getJwtToken();
            const refreshToken = userSession?.getRefreshToken().getToken();

            if(idToken === undefined || accessToken === undefined || refreshToken === undefined) {
                throw new Error("idToken, accessToken, or refreshToken is undefined");
            }

            const processUserResult = await _userService.processUser(
                {
                    IdToken: idToken,
                    AccessToken: accessToken,
                    RefreshToken: refreshToken,
                } as ProcessUser
            ) // my backend returns UserAlreadyExists

            console.log(user);
            console.log(processUserResult);

        } catch(error) {
            console.warn(error);
        }
    };

enter image description here

enter image description here

I want to prevent my backend to get called multiple times, any thoughts on how to stop this?

  • You can try setting flag on first event call and ignore others

    – 

Leave a Comment