React NextJs Ionic Capacitor Android Google Map Showing Gray Screen Unless I Drag Around

I am using the @react-google-maps/api. This library works on iOS and the web, and the API token also works.

when the android app loads (the map will remain gray):

after I drag the gray map around with my cursor, the gray tiles will load into map chunks (on emulator):

gMap.tsx:

import React from "react";
import gMapStyles from "./gMapStyles";
import { connect } from 'react-redux';
import {
  GoogleMap,
} from "@react-google-maps/api";

const mapContainerStyle = {
  height: "100vh",
  width: "100vw",
};

const options = {
  styles: gMapStyles,
  disableDefaultUI: true,
  zoomControl: false,
};

const center = {
  lat: 43.6532,
  lng: -79.3832,
};

const GMap = () => {

  return (
    <GoogleMap
      id="map"
      mapContainerStyle={mapContainerStyle}
      zoom={9}
      center={center}
      options={options}
    >

    </GoogleMap>
  );
}

export default connect(
  null,
  {}
)(GMap);

locationFunctions.tsx:

import GMap from './fragements/gMap';
import LocationSearchInput from "./fragements/locationSearchInput"
import LocationSearchSuggestions from "./fragements/locationSearchSuggestions"

import {
  useLoadScript
} from "@react-google-maps/api";

interface IProps {
  render: string;
}

const libraries = []
libraries.push("places");

const LocationFunctions = (props: IProps) => {
  const { isLoaded, loadError } = useLoadScript({
    googleMapsApiKey: "MY_API_KEY",
    libraries,
  });

  if (loadError) return <div>Error</div>;
  if (!isLoaded) return <div></div>;

  const component = () => {
    switch(props.render) {

      case "GMap":                              return <GMap/>;
      case "LocationSearchInputDeparture":      return <LocationSearchInput inputType="departure"/>;
      case "LocationSearchInputDestination":    return <LocationSearchInput inputType="destination"/>;
      case "LocationSearchSuggestions":         return <LocationSearchSuggestions/>;

      default:                                  return <h1>component not found</h1>
    }
  }

  return (
    <div>{ component() }</div>
  );
}

export default LocationFunctions

app.tsx

import React, { Fragment } from 'react';
import { Route } from 'react-router-dom';
import { IonApp, setupIonicReact, IonRouterOutlet } from '@ionic/react';
import { IonReactRouter } from '@ionic/react-router';
import { Provider } from 'react-redux';
import configureStore from '../store.config';
import dynamic from 'next/dynamic';

setupIonicReact({
  mode: 'md'
});

const store = configureStore((window as any).__PRELOADED_STATE__);

const Initialize = dynamic(() => import('./view/utility/initialize'));
const LocationFunctions = dynamic(() => import('./view/utility/locationFunctions'));
const Home = dynamic(() => import('./view/home/view'));
const Review = dynamic(() => import('./view/review/view'));
const ScheduleRide = dynamic(() => import('./view/schedule/view'));
const Ride = dynamic(() => import('./view/ride/view'));
const Menu = dynamic(() => import('./view/menu/view'));

const App = () => {
  return (
    <IonApp>
      <Provider store={store}>
        <IonReactRouter>
          <IonRouterOutlet id="main">
            <Fragment>
              <Initialize/>
              <LocationFunctions render={"GMap"}/>
              <Route path="/" component={Home} exact={true}/>
              <Route path="/review" component={Review} exact={true}/>
              <Route path="/schedule-ride*" component={ScheduleRide} exact={true}/>
              <Route path="/ride*" component={Ride} exact={true}/>
              <Route path="/menu" component={Menu} exact={true}/>
            </Fragment>
          </IonRouterOutlet>
        </IonReactRouter>
      </Provider>
    </IonApp>
  );
};

export default App;

relevant package.json versions:

    "@capacitor/android": "^3.5.1",
    "@capacitor/cli": "^3.5.1",
    "@capacitor/core": "^3.5.1",
    "@capacitor/geolocation": "^1.3.1",
    "@capacitor/ios": "^3.5.1",
    "@capacitor/storage": "^1.2.5",
    "@ionic/react": "^6.1.4",
    "@ionic/react-router": "^6.1.4",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^5.3.0",

I’m new to ionic and I couldn’t find a similar issue on the forum, please help!

Try setting the the --background of your <IonContent> to transparent.

Or, use a setTimeout around your map loading.

All I can say is bless your soul.

setTimeout worked like magic:

  const [loadMap, setLoadMap] = useState<boolean>(false)

  useEffect(() => { // I don't know why, but we can't load map tiles on android until a bit of a delay, maybe something with Next?
    setTimeout(() => setLoadMap(true), 500) //loading page
  }, []);

  if (!loadMap) {
    return(
      <div>loading...</div>
    )
  } else if(loadMap) {
    return (
      <GoogleMap>
      </GoogleMap>
    );
  }
1 Like