Skip to content

Commit 5d7d410

Browse files
committed
header remove firebase hook
1 parent a2aed6b commit 5d7d410

5 files changed

Lines changed: 40 additions & 45 deletions

File tree

src/app/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import './App.css';
44
import AppRouter from './router/Router';
55
import { MemoryRouter } from 'react-router-dom';
66
import { Suspense } from 'react';
7-
import { useAuthReady } from './components/AuthSessionProvider';
7+
import { useAuthSession } from './components/AuthSessionProvider';
88
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
99
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
1010
import AppContainer from './AppContainer';
@@ -30,7 +30,7 @@ function buildPathFromNextRouter(
3030
}
3131

3232
function App({ locale }: AppProps): React.ReactElement {
33-
const isAppReady = useAuthReady();
33+
const { isAuthReady: isAppReady } = useAuthSession();
3434

3535
const pathname = usePathname();
3636
const searchParams = useSearchParams();

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
type AllFeedsParams,
77
} from '../../../services/feeds/utils';
88
import { getUserAccessToken } from '../../../services/profile-service';
9-
import { useAuthReady } from '../../../components/AuthSessionProvider';
9+
import { useAuthSession } from '../../../components/AuthSessionProvider';
1010
import {
1111
getDataTypeParamFromSelectedFeedTypes,
1212
getInitialSelectedFeedTypes,
@@ -158,7 +158,7 @@ export function useFeedsSearch(searchParams: URLSearchParams): {
158158
isError: boolean;
159159
searchLimit: number;
160160
} {
161-
const authReady = useAuthReady();
161+
const { isAuthReady: authReady } = useAuthSession();
162162
const { cache } = useSWRConfig();
163163
const derivedSearchParams = deriveSearchParams(searchParams);
164164
const key = authReady ? buildSwrKey(derivedSearchParams) : null;

src/app/components/AuthSessionProvider.spec.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@testing-library/react';
88
import { configureStore } from '@reduxjs/toolkit';
99
import { Provider } from 'react-redux';
10-
import { AuthSessionProvider, useAuthReady } from './AuthSessionProvider';
10+
import { AuthSessionProvider, useAuthSession } from './AuthSessionProvider';
1111
import { setUserCookieSession } from '../services/session-service';
1212
import { anonymousLogin } from '../store/profile-reducer';
1313

@@ -97,34 +97,34 @@ afterEach(() => {
9797
});
9898

9999
describe('AuthSessionProvider', () => {
100-
describe('useAuthReady', () => {
100+
describe('useAuthSession', () => {
101101
it('returns false before any auth state change', () => {
102-
const { result } = renderHook(() => useAuthReady(), { wrapper });
103-
expect(result.current).toBe(false);
102+
const { result } = renderHook(() => useAuthSession(), { wrapper });
103+
expect(result.current.isAuthReady).toBe(false);
104104
});
105105

106106
it('returns true after onIdTokenChanged fires with a user', async () => {
107-
const { result } = renderHook(() => useAuthReady(), {
107+
const { result } = renderHook(() => useAuthSession(), {
108108
wrapper: wrapperWithAuth,
109109
});
110110

111111
await act(async () => {
112112
capturedAuthCallback(mockUser);
113113
});
114114

115-
expect(result.current).toBe(true);
115+
expect(result.current.isAuthReady).toBe(true);
116116
});
117117

118118
it('returns false after onIdTokenChanged fires with null', async () => {
119-
const { result } = renderHook(() => useAuthReady(), {
119+
const { result } = renderHook(() => useAuthSession(), {
120120
wrapper: wrapperWithAuth,
121121
});
122122

123123
await act(async () => {
124124
capturedAuthCallback(null);
125125
});
126126

127-
expect(result.current).toBe(false);
127+
expect(result.current.isAuthReady).toBe(false);
128128
});
129129
});
130130

src/app/components/AuthSessionProvider.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,23 @@ import { app } from '../../firebase';
1414
import { anonymousLogin } from '../store/profile-reducer';
1515
import { setUserCookieSession } from '../services/session-service';
1616

17-
const AuthReadyContext = createContext(false);
17+
interface AuthSession {
18+
isAuthReady: boolean;
19+
email: string | null;
20+
isAuthenticated: boolean;
21+
}
22+
23+
const AuthReadyContext = createContext<AuthSession>({
24+
isAuthReady: false,
25+
email: null,
26+
isAuthenticated: false,
27+
});
1828

1929
/**
20-
* Returns true once a Firebase user (anonymous or authenticated) is
21-
* available. Use this instead of registering your own
22-
* `onAuthStateChanged` listener.
30+
* Returns the current auth session state once Firebase has resolved.
31+
* Use this instead of registering your own `onAuthStateChanged` listener.
2332
*/
24-
export function useAuthReady(): boolean {
33+
export function useAuthSession(): AuthSession {
2534
return useContext(AuthReadyContext);
2635
}
2736

@@ -45,7 +54,11 @@ export function AuthSessionProvider({
4554
children: ReactNode;
4655
}): ReactElement {
4756
const dispatch = useDispatch();
48-
const [isAuthReady, setIsAuthReady] = useState(false);
57+
const [session, setSession] = useState<AuthSession>({
58+
isAuthReady: false,
59+
email: null,
60+
isAuthenticated: false,
61+
});
4962
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
5063

5164
useEffect(() => {
@@ -56,7 +69,11 @@ export function AuthSessionProvider({
5669
}
5770

5871
if (user != null) {
59-
setIsAuthReady(true);
72+
setSession({
73+
isAuthReady: true,
74+
email: user.email ?? null,
75+
isAuthenticated: !user.isAnonymous,
76+
});
6077
setUserCookieSession().catch(() => {});
6178

6279
// Check every 5 minutes; the cookie lasts 60 minutes, so this ensures renewal well before expiry
@@ -69,7 +86,7 @@ export function AuthSessionProvider({
6986
5 * 60 * 1000,
7087
); // 5 minutes
7188
} else {
72-
setIsAuthReady(false);
89+
setSession({ isAuthReady: false, email: null, isAuthenticated: false });
7390
dispatch(anonymousLogin());
7491
}
7592
});
@@ -81,7 +98,7 @@ export function AuthSessionProvider({
8198
}, [dispatch]);
8299

83100
return (
84-
<AuthReadyContext.Provider value={isAuthReady}>
101+
<AuthReadyContext.Provider value={session}>
85102
{children}
86103
</AuthReadyContext.Provider>
87104
);

src/app/components/Header.tsx

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import { animatedButtonStyling } from './Header.style';
4343
import ThemeToggle from './ThemeToggle';
4444
import { useTranslations, useLocale } from 'next-intl';
4545
import Link from 'next/link';
46-
import { app } from '../../firebase';
46+
import { useAuthSession } from './AuthSessionProvider';
4747

4848
// Lazy load components not needed for initial render
4949
const LogoutConfirmModal = dynamic(
@@ -74,9 +74,7 @@ function useClientSearchParams(): URLSearchParams | null {
7474
}
7575

7676
export default function DrawerAppBar(): React.ReactElement {
77-
const [currentUser, setCurrentUser] = React.useState<
78-
{ email: string; isAuthenticated: boolean } | undefined
79-
>(undefined);
77+
const { email: userEmail, isAuthenticated } = useAuthSession();
8078
const clientSearchParams = useClientSearchParams();
8179
const hasTransitFeedsRedirectParam =
8280
clientSearchParams?.get('utm_source') === 'transitfeeds';
@@ -95,23 +93,6 @@ export default function DrawerAppBar(): React.ReactElement {
9593
const { config } = useRemoteConfig();
9694
const t = useTranslations('common');
9795

98-
React.useEffect(() => {
99-
const auth = app.auth();
100-
const unsubscribe = auth.onAuthStateChanged(async (user) => {
101-
if (user != null) {
102-
setCurrentUser({
103-
email: user.email ?? '',
104-
isAuthenticated: !user.isAnonymous,
105-
});
106-
} else {
107-
setCurrentUser(undefined);
108-
}
109-
});
110-
return () => {
111-
unsubscribe();
112-
};
113-
}, []);
114-
11596
React.useEffect(() => {
11697
if (hasTransitFeedsRedirectParam) {
11798
setHasTransitFeedsRedirect(true);
@@ -128,9 +109,6 @@ export default function DrawerAppBar(): React.ReactElement {
128109

129110
const router = useRouter();
130111

131-
const isAuthenticated = currentUser != null && currentUser.isAuthenticated;
132-
const userEmail = currentUser?.email;
133-
134112
const handleDrawerToggle = (): void => {
135113
setMobileOpen((prevState) => !prevState);
136114
};

0 commit comments

Comments
 (0)