Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
react-native-google-places-session
Advanced tools
iOS/Android Google Places Widgets (Autocomplete Modals) and API Services for React Native Apps
iOS/Android Google Places Widgets (Autocomplete Modal) and API Services for React Native Apps
npm i react-native-google-places --save
OR
yarn add react-native-google-places
gem install cocoapods
to set it up the first time. (Hint: Go grab a cup of coffee!)cd ios && pod init
at the root directory of your project. This would create a Podfile
in your ios
directory.react-native link react-native-google-places
at the root directory of your project and ensure you edit your Podfile to look like the sample below (remove all the targets you are not building for, such as Tests and tvOS):# platform :ios, '9.0'
target '_YOUR_PROJECT_TARGET_' do
# Pods for _YOUR_PROJECT_TARGET_
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge',
'DevSupport',
'RCTText',
'RCTImage',
'RCTNetwork',
'RCTWebSocket',
'RCTSettings',
'RCTAnimation',
'RCTLinkingIOS',
# Add any other subspecs you want to use in your project
# Remove any subspecs you don't want to use in your project
]
pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
# This should already be auto-added for you, if not add the line below
pod 'react-native-google-places', :path => '../node_modules/react-native-google-places'
end
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == 'react-native-google-places'
target.build_configurations.each do |config|
config.build_settings['CLANG_ENABLE_MODULES'] = 'No'
end
end
if target.name == "React"
target.remove_from_project
end
end
end
pod install
from your ios
directory..xcworkspace
file to open the project. Or just use the react-native run-ios
command as usual to run your app in the simulator.AppDelegate.m
file, import the Google Places library by adding@import GooglePlaces;
@import GoogleMaps;
on top of the file.
didFinishLaunchingWithOptions
method, instantiate the library as follows - read about a better way to secure this below:[GMSPlacesClient provideAPIKey:@"YOUR_IOS_API_KEY_HERE"];
[GMSServices provideAPIKey:@"YOUR_IOS_API_KEY_HERE"];
NSLocationWhenInUseUsageDescription
and NSLocationAlwaysAndWhenInUseUsageDescription
in your info.plist
file, either using Xcode or manually editing the file e.g.<key>NSLocationWhenInUseUsageDescription</key>
<string>RNGPDemos needs your location to show you places</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>RNGPDemos needs your location to show you places</string>
react-native link react-native-google-places
. Or you can run the command now if you have not already.AndroidManifest.xml
file, request the following permissions:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
/android/gradle.properties
file, add your API key, read about a better way to secure this belowRNGP_ANDROID_API_KEY=Insert_API_KEY_here
react-native link react-native-google-places
. Otherwise, do the following or just ensure they are in place;android/settings.gradle
file:include ':react-native-google-places'
project(':react-native-google-places').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-google-places/android')
android/app/build.grade
file:dependencies {
...
compile project(':react-native-google-places')
}
android/build.gradle
file:allprojects {
repositories {
...
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
maven {
url "https://maven.google.com"
}
}
}
...MainApplication.java
file:import com.arttitude360.reactnative.rngoogleplaces.RNGooglePlacesPackage;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
...
new RNGooglePlacesPackage() //<-- Add line
);
}
Java 1.8 or above
. Add the following in your /android/app/build.gradle
file:android {
defaultConfig {
...
multiDexEnabled true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
react-native run-android
to get started.import RNGooglePlaces from 'react-native-google-places';
class GPlacesDemo extends Component {
openSearchModal() {
RNGooglePlaces.openAutocompleteModal()
.then((place) => {
console.log(place);
// place represents user's selection from the
// suggestions and it is a simplified Google Place object.
})
.catch(error => console.log(error.message)); // error is a Javascript Error object
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={() => this.openSearchModal()}
>
<Text>Pick a Place</Text>
</TouchableOpacity>
</View>
);
}
}
To customize autocomplete results as listed for Android and iOS in the official docs, you can pass an options
object as a parameter to the openAutocompleteModal()
method as follows:
RNGooglePlaces.openAutocompleteModal({
initialQuery: 'vestar',
locationRestriction: {
latitudeSW: 6.3670553,
longitudeSW: 2.7062895,
latitudeNE: 6.6967964,
longitudeNE: 4.351055
},
country: 'NG',
type: 'establishment'
}, [
'placeID', 'location', 'name', 'address', 'types', 'openingHours', 'plusCode', 'rating', 'userRatingsTotal', 'viewport'
])
.then((place) => console.log(place))
.catch(error => console.log(error.message));
OPTIONS
type
(String) - The type of results to return. Can only be one of (geocode
, address
, establishment
, regions
, and cities
). (optional)country
(String) - Limit results to a specific country using a ISO 3166-1 Alpha-2 country code (case insensitive). If this is not set, no country filtering will take place. (optional)locationBias
(Object) - To bias autocomplete results to a specific geographic region, pass an object (with the keys: latitudeNE
(Number), longitudeNE
(Number), latitudeSW
(Number), longitudeSW
(Number)) representing the bounding box for the region. (optional)locationRestriction
(Object) - To restrict autocomplete results to a specific geographic region, pass an object (with the keys: latitudeNE
(Number), longitudeNE
(Number), latitudeSW
(Number), longitudeSW
(Number)) representing the bounding box for the region. (optional)useOverlay
(Boolean) [Android Only] - If true, the autocomplete modal will open as an overlay rather than fullscreen. Defaults to false
.initialQuery
(String) [Android Only] - If present, the autocomplete modal would launch with results pre-populated for the query passed (optional).NOTE - On iOS, only one of locationBias
or locationRestriction
is respected, when passing both, only the first passed option would be used.
PLACE FIELDS
placeFields
as the second param to openAutocompleteModal
.Array
of String
such as placeID
, location
, name
, address
, types
, openingHours
, plusCode
, rating
, userRatingsTotal
, viewport
, website
, phoneNumber
, plusCode
and addressComponents
(available in v3.0.1+).{
priceLevel: 0,
viewport: {
longitudeSW: 3.320172219708498,
latitudeSW: 6.572546249999999,
longitudeNE: 3.322870180291502,
latitudeNE: 6.584909250000001
},
address: 'Lagos, Nigeria',
location: {
longitude: 3.3211348,
latitude: 6.5818185
},
addressComponents: [
{ shortName: 'Lagos', name: 'Lagos', types: [ 'locality', 'political' ] },
{ shortName: 'LA', name: 'Lagos', types: [ 'administrative_area_level_1', 'political' ] },
{ shortName: 'NG', name: 'Nigeria', types: [ 'country', 'political' ] }
],
userRatingsTotal: 939,
plusCode: {
globalCode: '6FR5H8JC+PF',
compoundCode: 'H8JC+PF Lagos, Nigeria'
},
rating: 3.2,
types: [ 'airport', 'point_of_interest', 'establishment' ],
attributions: [],
placeID: 'ChIJhRTXUeeROxARmk_Rp3PtIvI',
name: 'Murtala Muhammed International Airport'
}
Promise
from calling RNGooglePlaces.openAutocompleteModal()
are dependent on the selected place - as phoneNumber, website, north, south, east, west, priceLevel, rating
are not set on all Google Place
objects.This method returns to you the place where the device is currently located. That is, the place at the device's currently-reported location. For each place, the result includes an indication of the likelihood that the place is the right one. A higher value for likelihood
means a greater probability that the place is the best match. Ensure you have required the appropriate permissions, as stated post-install steps above, before making this request.
RNGooglePlaces.getCurrentPlace()
.then((results) => console.log(results))
.catch((error) => console.log(error.message));
OR
RNGooglePlaces.getCurrentPlace(['placeID', 'location', 'name', 'address'])
.then((results) => console.log(results))
.catch((error) => console.log(error.message));
PLACE FIELDS
placeFields
as the only param to getCurrentPlace
.Array
of String
such as placeID
, location
, name
, address
, types
, openingHours
, plusCode
, rating
, userRatingsTotal
, viewport
.website
, phoneNumber
, phoneNumber
and addressComponents
are not supported when calling getCurrentPlace
.[{
name: 'Facebook HQ',
website: 'https://www.facebook.com/',
longitude: -122.14835169999999,
address: '1 Hacker Way, Menlo Park, CA 94025, USA',
latitude: 37.48485,
placeID: 'ChIJZa6ezJa8j4AR1p1nTSaRtuQ',
types: [ 'street_address', 'geocode' ],
phoneNumber: '+1 650-543-4800',
likelihood: 0.9663974,
...
},{
...
}]
The sum of the likelihoods in a given result set is always less than or equal to 1.0. Note that the sum isn't necessarily 1.0.
If you have specific branding needs or you would rather build out your own custom search input and suggestions list (think Uber
), you may profit from calling the API methods below which would get you autocomplete predictions programmatically using the underlying iOS and Android SDKs
.
Recommended read:
Calling the following methods (getAutocompletePredictions
and lookUpPlaceByID
) without a session token can result in unwanted expensive bills from Google. This happens because the Places APIs are billed by SKU. Usage is tracked for each Product SKU, and an API may have more than one Product SKU (more on the Usage and Billing link above).
This module exposes a function named beginAutocompleteSession
that once invoked will generate a Session Token on the module instance. This Session Token will be reused for each subsequent getAutocompletePredictions
and lookUpPlaceByID
calls. As of October 2019, Session Tokens MUST be renewed upon calling lookUpPlaceByID
, as this API call marks the "end" of a session for billing purposes. FORGETTING TO GENERATE A NEW SESSION TOKEN AFTER CALLING lookupPlaceById
CAN INCREASE YOUR BILL.
Example of how an Autocomplete Session would look like:
// Generate session token
RNGooglePlaces.beginAutocompleteSession();
// You might call this several times (as the user is typing his query)
RNGooglePlaces.getAutocompletePredictions('facebook')
.then((results) => this.setState({ predictions: results }))
.catch((error) => console.log(error.message));
// Lookup a place by its ID
RNGooglePlaces.lookUpPlaceByID('ChIJZa6ezJa8j4AR1p1nTSaRtuQ');
// Generate new session token in case your user cancels his selection and wants to continue searching
RNGooglePlaces.beginAutocompleteSession();
In case you want to make Places API calls without using a session token, a function named cancelAutocompleteSession
is also exposed. Invoking it will erase an existing Session Token.
RNGooglePlaces.cancelAutocompleteSession();
RNGooglePlaces.getAutocompletePredictions('facebook')
.then((results) => this.setState({ predictions: results }))
.catch((error) => console.log(error.message));
To filter autocomplete results as listed for Android and iOS in the official docs, you can pass an options
object as a second parameter to the getAutocompletePredictions()
method as follows:
RNGooglePlaces.getAutocompletePredictions('Lagos', {
type: 'cities',
country: 'NG'
})
.then((place) => {
console.log(place);
})
.catch(error => console.log(error.message));
OR
RNGooglePlaces.getAutocompletePredictions('pizza', {
type: 'establishments',
locationBias: {
latitudeSW: 6.3670553,
longitudeSW: 2.7062895,
latitudeNE: 6.6967964,
longitudeNE: 4.351055
}
})
.then((place) => {
console.log(place);
})
.catch(error => console.log(error.message));
type
(String) - The type of results to return. Can only be one of (geocode
, address
, establishment
, regions
, and cities
). (optional)country
(String) - Limit results to a specific country using a ISO 3166-1 Alpha-2 country code (case insensitive). If this is not set, no country filtering will take place. (optional)locationBias
(Object) - To bias autocomplete results to a specific geographic region, pass an object (with the keys: latitudeNE
(Number), longitudeNE
(Number), latitudeSW
(Number), longitudeSW
(Number)) representing the bounding box for the region. (optional)locationRestriction
(Object) - To restrict autocomplete results to a specific geographic region, pass an object (with the keys: latitudeNE
(Number), longitudeNE
(Number), latitudeSW
(Number), longitudeSW
(Number)) representing the bounding box for the region. (optional)NOTE - On iOS, only one of locationBias
or locationRestriction
is respected, when passing both, only the first passed option would be used.
[{
primaryText: 'Facebook HQ',
placeID: 'ChIJZa6ezJa8j4AR1p1nTSaRtuQ',
secondaryText: 'Hacker Way, Menlo Park, CA, United States',
fullText: 'Facebook HQ, Hacker Way, Menlo Park, CA, United States',
types: [ 'street_address', 'geocode' ]
}, {
primaryText: 'Facebook Way',
placeID: 'EitGYWNlYm9vayBXYXksIE1lbmxvIFBhcmssIENBLCBVbml0ZWQgU3RhdGVz',
secondaryText: 'Menlo Park, CA, United States',
fullText: 'Facebook Way, Menlo Park, CA, United States',
types: [ 'street_address', 'geocode' ]
}]
RNGooglePlaces.lookUpPlaceByID('ChIJZa6ezJa8j4AR1p1nTSaRtuQ')
.then((results) => console.log(results))
.catch((error) => console.log(error.message));
OR
RNGooglePlaces.lookUpPlaceByID('ChIJZa6ezJa8j4AR1p1nTSaRtuQ', ['placeID', 'location', 'name', 'address'])
.then((results) => console.log(results))
.catch((error) => console.log(error.message));
PLACE FIELDS
placeFields
as the second param to lookUpPlaceByID
.Array
of String
such as placeID
, location
, name
, address
, types
, openingHours
, plusCode
, rating
, userRatingsTotal
, viewport
, addressComponents
, website
, phoneNumber
, and phoneNumber
.{
name: 'Facebook HQ',
website: 'https://www.facebook.com/',
longitude: -122.14835169999999,
address: '1 Hacker Way, Menlo Park, CA 94025, USA',
latitude: 37.48485,
placeID: 'ChIJZa6ezJa8j4AR1p1nTSaRtuQ',
types: [ 'street_address', 'geocode' ],
phoneNumber: '+1 650-543-4800',
}
The typical use flow would be to call getAutocompletePredictions()
when the value of your search input changes to populate your suggestion listview and call lookUpPlaceByID()
to retrieve the place details when a place on your listview is selected.
getAutocompletePredictions()
method is subject to tiered query limits. See the documentation on Android & iOS Usage Limits.System Variables
before checking for it in your gradle.properties
file - this ensures you can totally keep your keys out of Version Control
.gradle.properties
, if already defined. Define a system variable representing your Android API key e.g. on a Unix/Mac terminal run:export RNGP_ANDROID_API_KEY=Insert_API_KEY_here
~/.bash_profile
file or similar files.CI/CD
build and you should be fine.gradle.properties
, things would work just as fine.You would have to do a bit more work to properly secure and move your API key out of Version Control than we did for Android.
Gemfile
to the root of your /ios
folder with the following or similar content:source 'https://rubygems.org'
gem 'cocoapods'
gem 'cocoapods-keys'
/ios
directory:gem install cocoapods-keys
Podfile
like below:plugin 'cocoapods-keys'
target 'YourApp' do
# Pods for YourApp
pod 'GoogleMaps'
pod 'GooglePlaces'
end
cocoapods-keys
repo to learn how to add your API key to keychain on the Mac.cocoapods-keys
with either of the instructions from the line above.pod install
again from your /ios
directory.AppDelegate.m
file. You can review a sample usage in the Sample AppAppDelegate.m
, things would work just as fine.Ensure you have automatically/manually linked dependencies and/or re-run the build after doing so.
react-native link
Manual Linking With Your Project
steps above.react-native run-ios
On iOS, ensure you have installed the native dependencies with Cocoapods.
The MIT License.
FAQs
iOS/Android Google Places Widgets (Autocomplete Modals) and API Services for React Native Apps
The npm package react-native-google-places-session receives a total of 0 weekly downloads. As such, react-native-google-places-session popularity was classified as not popular.
We found that react-native-google-places-session demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.