Skip to content

Commit d8483c7

Browse files
committed
centralized the auth state change
1 parent 85990df commit d8483c7

3 files changed

Lines changed: 7 additions & 58 deletions

File tree

src/app/App.tsx

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
import './App.css';
44
import AppRouter from './router/Router';
55
import { MemoryRouter } from 'react-router-dom';
6-
import { useDispatch } from 'react-redux';
7-
import { anonymousLogin } from './store/profile-reducer';
8-
import { app } from '../firebase';
9-
import { Suspense, useEffect, useState } from 'react';
6+
import { Suspense } from 'react';
7+
import { useAuthReady } from './components/AuthSessionProvider';
108
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
119
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
1210
import AppContainer from './AppContainer';
@@ -32,29 +30,13 @@ function buildPathFromNextRouter(
3230
}
3331

3432
function App({ locale }: AppProps): React.ReactElement {
35-
const dispatch = useDispatch();
36-
const [isAppReady, setIsAppReady] = useState(false);
33+
const isAppReady = useAuthReady();
3734

3835
const pathname = usePathname();
3936
const searchParams = useSearchParams();
4037

4138
const initialPath = buildPathFromNextRouter(pathname, searchParams, locale);
4239

43-
useEffect(() => {
44-
const unsubscribe = app.auth().onAuthStateChanged((user) => {
45-
if (user != null) {
46-
setIsAppReady(true);
47-
} else {
48-
setIsAppReady(false);
49-
dispatch(anonymousLogin());
50-
}
51-
});
52-
dispatch(anonymousLogin());
53-
return () => {
54-
unsubscribe();
55-
};
56-
}, [dispatch]);
57-
5840
return (
5941
<Suspense>
6042
<LocalizationProvider dateAdapter={AdapterDayjs}>

src/app/[locale]/feeds/lib/useFeedsSearch.ts

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
'use client';
2-
import { useEffect, useState } from 'react';
32
import useSWR, { useSWRConfig } from 'swr';
43
import { searchFeeds } from '../../../services/feeds';
54
import {
65
type AllFeedsType,
76
type AllFeedsParams,
87
} from '../../../services/feeds/utils';
98
import { getUserAccessToken } from '../../../services/profile-service';
10-
import { app } from '../../../../firebase';
9+
import { useAuthReady } from '../../../components/AuthSessionProvider';
1110
import {
1211
getDataTypeParamFromSelectedFeedTypes,
1312
getInitialSelectedFeedTypes,
@@ -18,39 +17,6 @@ const SEARCH_LIMIT = 20;
1817
// This is for client-side caching
1918
const CACHE_TTL_MS = 60 * 30 * 1000; // 30 minutes - controls how long search results are cached in SWR
2019

21-
/**
22-
* Ensures a Firebase user exists (anonymous or authenticated) before
23-
* SWR attempts to fetch. If no user is signed in, triggers anonymous
24-
* sign-in — the same thing App.tsx does for legacy React Router pages.
25-
* This is needed for the access token
26-
*
27-
* TODO: Revisit this logic to be used at a more global level without slowing down the initial load of all pages that don't require auth (e.g. about, contact). For example, we could move this logic to a context provider that's used only on the feeds page and its children.
28-
*/
29-
function useFirebaseAuthReady(): boolean {
30-
const [isReady, setIsReady] = useState(() => app.auth().currentUser !== null);
31-
32-
useEffect(() => {
33-
const unsubscribe = app.auth().onAuthStateChanged((user) => {
34-
if (user !== null) {
35-
setIsReady(true);
36-
} else {
37-
// No user — trigger anonymous sign-in (mirrors App.tsx behavior)
38-
setIsReady(false);
39-
app
40-
.auth()
41-
.signInAnonymously()
42-
.catch(() => {
43-
// Auth listener will handle the state update on success;
44-
// if sign-in fails, isReady stays false and SWR won't fetch.
45-
});
46-
}
47-
});
48-
return unsubscribe;
49-
}, []);
50-
51-
return isReady;
52-
}
53-
5420
/**
5521
* Derives all API query params from the URL search params.
5622
* This is the single source of truth — no duplicated React state.
@@ -192,7 +158,7 @@ export function useFeedsSearch(searchParams: URLSearchParams): {
192158
isError: boolean;
193159
searchLimit: number;
194160
} {
195-
const authReady = useFirebaseAuthReady();
161+
const authReady = useAuthReady();
196162
const { cache } = useSWRConfig();
197163
const derivedSearchParams = deriveSearchParams(searchParams);
198164
const key = authReady ? buildSwrKey(derivedSearchParams) : null;

src/app/providers.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { type RemoteConfigValues } from './interface/RemoteConfig';
88
// Look into this provider and see if it's client blocking. Niche provider might be able to isolate for single use
99
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
1010
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
11+
import { AuthSessionProvider } from './components/AuthSessionProvider';
1112

1213
interface ProvidersProps {
1314
children: React.ReactNode;
@@ -35,7 +36,7 @@ export function Providers({
3536
<ContextProviders>
3637
<RemoteConfigProvider config={remoteConfig}>
3738
<LocalizationProvider dateAdapter={AdapterDayjs}>
38-
{children}
39+
<AuthSessionProvider>{children}</AuthSessionProvider>
3940
</LocalizationProvider>
4041
</RemoteConfigProvider>
4142
</ContextProviders>

0 commit comments

Comments
 (0)