rn-native-places
v1.0.0
Published
React Native Native Module for Google Places Autocomplete using the native SDK. Supports platform-restricted API keys (Android SHA-1 + iOS Bundle ID).
Maintainers
Readme
rn-native-places
By Ibrahim Hamed · GitHub
A React Native native module that wraps the Google Places SDK for both Android (Kotlin) and iOS (Swift) to enable platform-restricted API keys (SHA-1 / Bundle ID).
Why This Exists
Every JS-based Google Places library (react-native-google-places-autocomplete, etc.) makes HTTP requests from JavaScript. Those requests are sent from an IP address — not from the app itself. This means:
- ❌ You cannot use Android SHA-1 key restrictions
- ❌ You cannot use iOS Bundle ID restrictions
- ❌ Your API key is exposed and can be abused
This module calls the native Google Places SDK directly (Java/Kotlin on Android, Swift on iOS). Native SDK calls include the app signature automatically:
- ✅ Android: Signs requests with SHA-1 certificate fingerprint
- ✅ iOS: Signs requests with Bundle ID
- ✅ API key restrictions work perfectly
Installation
npm install rn-native-places
# or
yarn add rn-native-placesAndroid Setup
- Add the Places SDK dependency to
android/app/build.gradle:
dependencies {
implementation 'com.google.android.libraries.places:places:2.7.0'
}- Add your API key to
android/app/src/main/AndroidManifest.xml:
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_ANDROID_API_KEY" />- Register the package in
MainApplication.kt:
import com.yourpackage.NativePlacesPackage
override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply {
add(NativePlacesPackage())
}- Copy
android/NativePlacesModule.ktandandroid/NativePlacesPackage.ktinto your Android source directory (e.g.android/app/src/main/java/com/yourapp/), and update thepackagedeclaration at the top of each file.
iOS Setup
- Add GooglePlaces to your
Podfile:
pod 'GooglePlaces', '~> 9.0'Run
pod install.Initialize the Places client in
AppDelegate.swift:
import GooglePlaces
// Inside application(_:didFinishLaunchingWithOptions:)
GMSPlacesClient.provideAPIKey("YOUR_IOS_API_KEY")- Copy
ios/NativePlacesAutocomplete.swiftandios/NativePlacesAutocomplete.minto your Xcode project, making sure to add them to your app target in Xcode (check the Target Membership box).
Usage
import { getAutocompletePredictions, getPlaceDetails, resetSession } from 'rn-native-places';
// Autocomplete search
const predictions = await getAutocompletePredictions('New York', 'us');
// Returns: PlacePrediction[]
// Get place details
const details = await getPlaceDetails(predictions[0].place_id);
// Returns: PlaceDetails
// Reset autocomplete session token (call after user selects a place)
await resetSession();API
getAutocompletePredictions(query: string, countryCode?: string): Promise<PlacePrediction[]>
Returns autocomplete predictions for the given query.
| Param | Type | Description |
|-------|------|-------------|
| query | string | Search text |
| countryCode | string | ISO 3166-1 alpha-2 country code (default: 'us') |
getPlaceDetails(placeId: string): Promise<PlaceDetails>
Returns full details for a place by its Place ID.
resetSession(): Promise<void>
Resets the autocomplete session token. Call this after the user selects a place to start a fresh billing session.
Types
interface PlacePrediction {
place_id: string;
description: string;
main_text: string;
secondary_text: string;
}
interface AddressComponent {
long_name: string;
short_name: string;
types: string[];
}
interface PlaceDetails {
place_id: string;
name: string;
formatted_address: string;
latitude: number;
longitude: number;
address_components: AddressComponent[];
}Google Cloud Console Configuration
- Enable Places API and Places API (New)
- Create two separate API keys:
Android Key:
- Application restrictions → Android apps
- Add package name + SHA-1 fingerprint (both debug and release)
- API restrictions → Places API, Places API (New), Maps SDK for Android
iOS Key:
- Application restrictions → iOS apps
- Add Bundle ID
- API restrictions → Places API, Places API (New), Maps SDK for iOS
Get your SHA-1 fingerprints:
# Debug
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android
# Release
keytool -list -v -keystore your-release.jks -alias your-aliasHow It Works
User types → JS calls NativeModule → Kotlin/Swift SDK call → Google servers
↑
App signature attached automatically
(SHA-1 for Android, Bundle ID for iOS)When you call the native SDK, Google's SDK attaches your app's signature to the request automatically — no manual signing required. Google's servers verify the signature matches the key's restrictions.
Common Errors
| Error | Cause | Fix |
|-------|-------|-----|
| 9011: not authorized from IP | Still using an HTTP/JS call somewhere | Make sure you're calling the native module, not a web API |
| REQUEST_DENIED | Key restriction mismatch | Verify SHA-1 / Bundle ID in Google Console |
| NativeModule available: false (iOS) | Swift/ObjC files not added to Xcode target | Open Xcode → target → check file Target Membership |
| Places SDK not initialized | provideAPIKey() not called | Add to AppDelegate before any Places usage |
License
MIT — Ibrahim Hamed
🌐 ibrahimtoulba.com · 🐙 github.com/ibrahimhamed11
