Skip to content

Commit f2b493f

Browse files
Merge pull request #75 from MobilityData/fix/login-token-renewal
fix: login token renewal
2 parents c66f5d5 + a6974af commit f2b493f

File tree

10 files changed

+451
-108
lines changed

10 files changed

+451
-108
lines changed

.github/workflows/vercel-prod-on-release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: Deploy to Vercel Production on Release
22

33
on:
4-
workflow_dispatch:
54
release:
65
types: [published]
76

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 { useAuthSession } 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 { isAuthReady: isAppReady } = useAuthSession();
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]/components/HomePage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,23 @@ export default async function HomePage(): Promise<ReactElement> {
9191
mt: 4,
9292
}}
9393
>
94-
{t('servingOver')}
94+
{t('servingOver') + ' '}
9595
<Box
9696
component='span'
9797
sx={{ fontSize: 30, color: 'primary.main', mx: 1 }}
9898
itemProp='numberOfItems'
9999
>
100100
6000
101101
</Box>
102-
{t('feeds')}
102+
{' ' + t('feeds') + ' '}
103103
<Box
104104
component='span'
105105
sx={{ fontSize: 30, color: 'primary.main', mx: 1 }}
106106
itemProp='spatialCoverage'
107107
>
108108
99
109109
</Box>
110-
{t('countries')}
110+
{' ' + t('countries')}
111111
</Typography>
112112
<SearchBox />
113113
<Box

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 { useAuthSession } 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.
@@ -201,7 +167,7 @@ export function useFeedsSearch(searchParams: URLSearchParams): {
201167
isError: boolean;
202168
searchLimit: number;
203169
} {
204-
const authReady = useFirebaseAuthReady();
170+
const { isAuthReady: authReady } = useAuthSession();
205171
const { cache } = useSWRConfig();
206172
const derivedSearchParams = deriveSearchParams(searchParams);
207173
const key = authReady ? buildSwrKey(derivedSearchParams) : null;

0 commit comments

Comments
 (0)