Expo (32) MapView renders blank

Hi,

I’m after a bit of help with Google Maps, as it’s working in development, but not in production with a built APK where it just shows a blank screen with the Google logo at the bottom. I’ve seen this question around, but they’re generally a bit older and don’t contain any more than I’ve done already.

I’ve gone through these steps…

  • Add Expo MapView
  • Enabled Maps for Android SDK (Google Dev console)
  • Entered my package name and SHA-1 fingerprint from the Play Console (Google managed keys)

As I say, It works in development, but not when I build the APK.

I’m running RN 0.59 and Expo 32, but I think I may need to update Expo to 33 to build 64bit APKs?

Please, if anyone has any more to offer, I’d be very grateful!

Hey @kemikalgeneral,

Did you add your Google Maps API key to your app.json (either under the ios key, android key or both)?

https://docs.expo.io/versions/v34.0.0/workflow/configuration/

Cheers,
Adam

Hi @adamjnav, thanks for the reply.

Yes I have, under Android-Config-apiKey

@adamjnav Do you have any other ideas please, I really need this working.

Thanks

Can you share the relevant code for rendering the screen and your app.json file?

I might have the same issue. Map tiles are not rendering if I zoom in. If I zoom out a lot it does.

Only on the Play Store.

Hi @adamjnav,

Sure I can!
I’ve left out the styling code as it all works, just not in production.

Map


import React, {Component} from 'react';
import {ImageBackground, Linking, StyleSheet, Text, TextInput, TouchableOpacity, View} from 'react-native';
import {MapView, Permissions, SQLite} from 'expo';
import {MaterialIcons} from '@expo/vector-icons';

import PageBreak from './../../Components/PageBreak';

import colors from "../../Styles/colors";
import mainStyles from "../../Styles/styles";
import dimensions from "../../Styles/dimensions";

const db = SQLite.openDatabase('xxx.db');

export default class xxx extends Component {
    state = {
        isPermissionGranted: false,
        newTitle: '',
        newMessage: '',
        region: {
            latitude: 0,
            longitude: 0,
            latitudeDelta: 0.005,
            longitudeDelta: 0.005,
        },
        markers: [],
        selectedMarker: {},
        error: null,
        isFormHidden: true,
        isCalloutHidden: true,
    };

    // Get current location on page load
    componentDidMount() {
        this.checkLocationPermission();
    }

    // Check for permission to use the device's location
    checkLocationPermission = () => {
        Permissions.askAsync(Permissions.LOCATION)
            .then((response) => {
                if (response.status === 'granted') {
                    this.getLocation();

                    this.setState({isPermissionGranted: true});
                } else {
                    this.setState({isPermissionGranted: false});
                }
            })
            .catch((error) => {
                console.log('Map component location permission error: ', error);
            })
    };

    getLocation() {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({
                    region: {
                        latitude: position.coords.latitude,
                        longitude: position.coords.longitude,
                        latitudeDelta: 0.005,
                        longitudeDelta: 0.005,
                    },
                    error: null,
                });
            },
            (error) => this.setState({error: error.message}),
            {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
        );

        // Get markers from database
        this.getMarkersFromDB();
    }

// Get all markers from the database and add the to the state
    getMarkersFromDB() {
        db.transaction(tx => {
            tx.executeSql('select * from xxx', [], (_, {rows}) => {
                // console.log('DTT rows: ', rows._array);
                const dbRows = rows._array;

                const markersArray = [];
                this.setState({markers: []});

                // Map over the dbRows, creating a marker for each row
                // Push the row to the markers state
                dbRows.map((row) => {
                    let marker = {
                        marker: {
                            id: 0,
                            title: '',
                            message: '',
                            latLng: {
                                latitude: 0,
                                longitude: 0,
                            },
                        }
                    };

                    marker.marker.id = row.id;
                    marker.marker.title = row.title;
                    marker.marker.message = row.message;
                    marker.marker.latLng.latitude = row.latitude;
                    marker.marker.latLng.longitude = row.longitude;

                    markersArray.push(marker.marker);
                });

                this.setState({markers: markersArray});
            });
        });
    };

render() {
        return (
            <ImageBackground source={require('../../Assets/images/background.png')}
                             style={{width: '100%', height: '100%'}}>

                <View style={[{flex: 1}, mainStyles.pageColour]}>

                    {this.state.isPermissionGranted ?
                        <View style={{flex: 1}}>

                            {/***** Map *****/}
                            <MapView
                                style={{flex: 1}}
                                initialRegion={{
                                    latitude: this.state.region.latitude,
                                    longitude: this.state.region.longitude,
                                    latitudeDelta: this.state.region.latitudeDelta,
                                    longitudeDelta: this.state.region.longitudeDelta,
                                }}
                                showsUserLocation={true}
                                showsMyLocationButton={true}
                                showsScale={true}
                                loadingEnabled={true}
                                onPress={() => this.toggleCalloutVisibility('map')}>

                                {/***** Marker *****/}
                                {/*Render the list of Markers if there are any, click to open the Callout*/}
                                {this.state.markers.map(marker => (
                                    <MapView.Marker
                                        key={marker.id}
                                        identifier={`${marker.id}`}
                                        coordinate={marker.latLng}
                                        title={marker.title}
                                        description={marker.message}
                                        draggable={true}
                                        onPress={() => this.toggleCalloutVisibility('marker', marker)}>

                                        <MapView.Callout tooltip={true}>
                                            <View style={styles.calloutContainer}>
                                                <Text style={styles.calloutTitle}>{marker.title}</Text>
                                                <Text>{marker.message}</Text>
                                                <PageBreak/>
                                                <Text style={styles.latLngText}>Lat: {marker.latLng.latitude}</Text>
                                                <Text style={styles.latLngText}>Lng: {marker.latLng.longitude}</Text>
                                            </View>
                                        </MapView.Callout>

                                    </MapView.Marker>
                                ))}

                            </MapView>

                        </View>

                        :

                        <View style={styles.permissionContainer}>
                            <Text style={[mainStyles.smallText, styles.permissionText]}>
                                You need to grant location access to enable the Map</Text>
                        </View>
                    }

                </View>
            </ImageBackground>
        );
    }
}

App.json


{
  "expo": {
    "name": "xxx",
    "icon": "./App/Assets/images/xxx.png",
    "orientation": "portrait",
    "version": "0.3",
    "sdkVersion": "32.0.0",
    "android": {
      "package": "com.xxx.xxx",
      "versionCode": 3,
      "config": {
        "googleMaps": {
          "apiKey": "myApiKey"
        }
      }
    },
    "ios": {
      "bundleIdentifier": "com.xxx.xxx",
      "infoPlist": {
        "NSLocationWhenInUseUsageDescription": "This app uses your location for xxx"
      }
    }
  }
}

@caminoninja … I have the same issue (only) on iOS in development where it recognises my current location, but doesn’t jump to it, and is zoomed VERY far in.

@kemikalgeneral Any solution to your Android problem?

@adamjnav can you confirm its not a bug, I am facing the exact same problem my app was working absolutely fine a week ago. I have entered the Android keys as well, I am unable to locate whats wrong

@adamjnav Do you have any updates on this bug please?

It’s been 34 days and I REALLY need to get it sorted?

Thanks.

Update:

  • I’ve updated to SDK33
  • Installed and updated imports for all the packages that required it
  • Installed react-native-maps for the MapView
  • Added and checked Location permissions are working and granted…

…but it’s still the same, works in development, but not built in production, it just shows a blank screen with the Google logo in the corner :frowning:

Hey @kemikalgeneral,

Sorry for the delay here. I just built a fresh project, downgraded it to SDK33, created a new Google Maps API key for the project, built it and it’s working as expected. This leads me to believe it may be something with your API key or your implementation or perhaps with your location logic. MapView doesn’t need Location permissions to run unless you use the showsUserLocation prop.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.