Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Authentication Loading State Issue with Vite #1009

Open
nack43 opened this issue Jul 23, 2023 · 9 comments
Open

[BUG] Authentication Loading State Issue with Vite #1009

nack43 opened this issue Jul 23, 2023 · 9 comments
Assignees
Labels
bug Something isn't working

Comments

@nack43
Copy link

nack43 commented Jul 23, 2023

Describe the bug
I'm currently developing a sample app with Frontendegg's authentication, utilizing the React integration guide. However, I am using Vite instead of Create React App (CRA) for this project.

The authentication process works as expected, but I encountered an issue when trying to display a loading component during this process. It seems that the isLoading state from useAuth() consistently returns false.

I discovered the isLoading property by inspecting the return type of useAuth(). However, I found no mention of it in the existing documentation.

This leads me to two questions:

  1. Is there an API reference for the React SDK that might explain this isLoading property?
  2. How can I correctly obtain the loading state during the authentication process?

To Reproduce
Steps to reproduce the behavior:

  1. Go to integration guide for React
  2. Follow the instruction and build the app with Vite
  3. Change const { user, isAuthenticated } = useAuth() with const { user, isAuthenticated, isLoading } = useAuth()
  4. Return loading component when isLoading is true e.g. if (isLoading) return <div>Loading...</div>
  5. You can see it's not rendered.

Expected behavior
I expect the 'isLoading' state to consistently return 'true' during the entire authentication process.

Screenshots
n/a

import { useEffect } from "react";
import "./App.css";
import { ContextHolder, useAuth, useLoginWithRedirect } from "@frontegg/react";

function App() {
  const { user, isAuthenticated, isLoading } = useAuth();

  const loginWithRedirect = useLoginWithRedirect();

  useEffect(() => {
    if (!isAuthenticated) {
      loginWithRedirect();
    }
  }, [isAuthenticated, loginWithRedirect]);

  const logout = () => {
    const baseUrl = ContextHolder.getContext().baseUrl;
    window.location.href = `${baseUrl}/oauth/logout?post_logout_redirect_uri=${window.location}`;
  };

  // HERE: This div should be rendered but the 'Click me to login' button will be rendered 
  if (isLoading) return <div>Loading...</div>;

  return (
    <div className="App">
      {isAuthenticated ? (
        <div>
          <div>
            <img src={user?.profilePictureUrl || undefined} alt={user?.name} />
          </div>
          <div>
            <span>Logged in as: {user?.name}</span>
          </div>
          <div>
            <button onClick={() => alert(user?.accessToken)}>
              What is my access token?
            </button>
          </div>
          <button onClick={() => logout()}>Click to logout</button>
        </div>
      ) : (
        <div>
          <button onClick={() => loginWithRedirect()}>Click me to login</button>
        </div>
      )}
    </div>
  );
}

export default App;

Additional context
I am using

Vite: 4.4.5
React: 18.2.0
@frontegg/react: 5.0.46

Feel free to ask me anything if you guys need more information. Thanks.

@nack43 nack43 added the bug Something isn't working label Jul 23, 2023
@rotemzif1
Copy link
Contributor

Hey @nack43 thanks for the detailed explanation.
We are supporting an API for custom loader component, would that be what you are looking for? If so, I will provide an example.

In any way, the isLoading of auth state should be changed correctly, so I will check if there is an issue or suggest how to use it better.

@nack43
Copy link
Author

nack43 commented Jul 23, 2023

@rotemzif1 Thanks for your quick reply!

We are supporting an API for custom loader component, would that be what you are looking for? If so, I will provide an example.

Yes, that would be what I want 👍

In any way, the isLoading of auth state should be changed correctly, so I will check if there is an issue or suggest how to use it better

Thanks.

@rotemzif1
Copy link
Contributor

Great then this is an example of using a custom loader :) @nack43

import React, {useState} from "react";
import {FronteggProvider} from "@frontegg/react";
import {Dimmer, Loader} from "semantic-ui-react";

import contextOptions from './context-options';

const MyCustomLoaderComponent = () => {
    return (
        <Dimmer active>
            <Loader>Loading using custom loader!</Loader>
        </Dimmer>
    )
}
const Provider = () => {
    const [loading, setLoading] = useState(true);

    return (
        <div>
            <FronteggProvider customLoader={setLoading} contextOptions={contextOptions} headerImage={headerImage}>
                <div />
            </FronteggProvider>
            {loading && <MyCustomLoaderComponent />}
        </div>
    )
};

export default Provider;

@nack43
Copy link
Author

nack43 commented Jul 25, 2023

@rotemzif1 Thanks! I will try it this weekend.

@nack43
Copy link
Author

nack43 commented Jul 30, 2023

@rotemzif1

Thanks for your recommendations. I tried it, and it works.

Here is my working code.

const Provider = () => {
  const [loading, setLoading] = React.useState(false);

  return (
    <div>
      <FronteggProvider
        customLoader={setLoading}
        contextOptions={contextOptions}
        authOptions={authOptions}
      >
        <App />
      </FronteggProvider>
      {loading && <div>loading</div>}
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <Provider />
  </React.StrictMode>
);

However, I've still encountered an issue. Even though I understand that the isLoading state within the <App/> component becomes redundant—since the component does not render during the authentication process. but, I would like to use the isLoading state returned by the useAuth() hook.

Do you have any update on the situation regarding the potential bug in isLoading? If I have anything I can help, let me know. Thanks.

@rotemzif1
Copy link
Contributor

@nack43 yes you are correct the isLoading state should be up to date and currently, it doesn't. We are working on a fix that will be published soon. What is your use case? would be happy to hear in order to verify it will work for you.

@rotemzif1
Copy link
Contributor

rotemzif1 commented Aug 15, 2023

@nack43 hey we have just released a new version with the fix for is Loading, you should now have the proper behaviour, by adding a new flag to the FronteggProvider -

<FronteggProvider
          authOptions={{
              hostedLoginOptions: {
                  loadUserOnFirstLoad: true,
              }
          }}
          contextOptions={{
              ...
          }}
          hostedLoginBox={true}
      >
        <App/>
      </FronteggProvider>

can you please give it a try and let me know how it goes?

@eifr
Copy link

eifr commented Mar 20, 2024

@rotemzif1 loadUserOnFirstLoad blocks my app from starting without any option for a loading, tried to use customLoader and it only gets called on login and not on restore session (app refresh)

@eifr
Copy link

eifr commented Mar 20, 2024

I ended up creating this function to wrap my app:

const TriggerWhenMounted = ({
  children,
  onMounted,
}: {
  children: React.ReactNode;
  onMounted: () => void;
}) => {
  useEffect(() => {
    onMounted();
  }, [onMounted]);
  return children;
};

and this is the app:

function AppWithFrontegg() {
  const [loading, setLoading] = useState(true);
  return (
    <>
      {loading && <>loading</>}
      <FronteggProvider
        contextOptions={contextOptions}
        authOptions={authOptions}
        hostedLoginBox={true}
        customLoader={true}
      >
        <TriggerWhenMounted onMounted={() => setLoading(false)}>
          <App />
        </TriggerWhenMounted>
      </FronteggProvider>
    </>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants