The home screen passed its FlatList header as `ListHeaderComponent={() =>
(...)}`. VirtualizedList renders a function-valued header prop as
`<HeaderComponent />`, so a fresh arrow function on each render is a fresh
element type: React unmounted the entire header subtree — MapView included —
and mounted a new one. Home re-renders several times on mount (useFetch
loading->data, useUserLocation pending->granted, session resolve), and
recreating the Android GoogleMap surface each time left it grey with the
Google logo and tiles that never finished loading.
Pass the header as an element instead so the type stays stable and MapView
mounts once. The same `() => (...)` pattern in ListEmptyComponent here, and in
rides.tsx and confirm-ride.tsx, cost needless remounts of list chrome and
DriverCards; fixed alongside.
Also pin expo-crypto to ~13.0.2. It was ^57.0.1 — a wrong-major native module
for SDK 51 that nothing in the app imports. npm hoisted it to the top level
and gave expo-auth-session a nested 13.0.2 to satisfy its ~13.0.0 constraint,
leaving two copies of one native module in the tree for autolinking to choose
between.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
65 lines
2.1 KiB
JavaScript
65 lines
2.1 KiB
JavaScript
// Dynamic config layered over app.json.
|
|
//
|
|
// react-native-maps reads the Google Maps key from the *native* manifest
|
|
// (AndroidManifest `com.google.android.geo.API_KEY`), not from the JS bundle,
|
|
// so EXPO_PUBLIC_GOOGLE_API_KEY has to be injected here at build time. Without
|
|
// it Android renders an empty grey tile area instead of a map.
|
|
|
|
const googleMapsApiKey = process.env.EXPO_PUBLIC_GOOGLE_API_KEY;
|
|
|
|
const LOCATION_PERMISSION =
|
|
"Waseel uses your location to show nearby drivers and set your pickup point.";
|
|
|
|
module.exports = ({ config }) => {
|
|
if (!googleMapsApiKey) {
|
|
const message =
|
|
"EXPO_PUBLIC_GOOGLE_API_KEY is not set — the Android manifest will have no " +
|
|
"Maps key and the map will render blank.";
|
|
|
|
// `.env` is gitignored, so it is never uploaded to EAS. Unless the key is
|
|
// also registered as an EAS environment variable the build silently
|
|
// produces a keyless APK, and the blank map only shows up on the device.
|
|
// Fail the build here rather than shipping that.
|
|
if (process.env.EAS_BUILD) {
|
|
throw new Error(
|
|
`[app.config] ${message} Register it with \`eas env:create\` (or in the ` +
|
|
"EAS dashboard) for this build profile.",
|
|
);
|
|
}
|
|
|
|
console.warn(`[app.config] ${message}`);
|
|
}
|
|
|
|
return {
|
|
...config,
|
|
ios: {
|
|
...config.ios,
|
|
// iOS uses Apple Maps via PROVIDER_DEFAULT, so this only matters if the
|
|
// Map component is switched to PROVIDER_GOOGLE.
|
|
config: { ...config.ios?.config, googleMapsApiKey },
|
|
infoPlist: {
|
|
...config.ios?.infoPlist,
|
|
NSLocationWhenInUseUsageDescription: LOCATION_PERMISSION,
|
|
},
|
|
},
|
|
android: {
|
|
...config.android,
|
|
config: {
|
|
...config.android?.config,
|
|
googleMaps: { apiKey: googleMapsApiKey },
|
|
},
|
|
// Location permissions come from the expo-location plugin below.
|
|
},
|
|
plugins: [
|
|
...(config.plugins ?? []),
|
|
[
|
|
"expo-location",
|
|
{
|
|
locationAlwaysAndWhenInUsePermission: LOCATION_PERMISSION,
|
|
locationWhenInUsePermission: LOCATION_PERMISSION,
|
|
},
|
|
],
|
|
],
|
|
};
|
|
};
|