UNPKG

react-native-google-nearby-messages

Version:

An async Google Nearby Messages API Wrapper for React Native (Android & iOS)

203 lines (144 loc) 9.68 kB
<p align="center"> <img src="img/nearby-messages-icon.png" height="120" /> <h2 align="center">react-native-google-nearby-messages</h2> </p> An async **Google Nearby Messages** API Wrapper for **React Native** (Android & iOS), supporting autolinking, custom discovery modes (`broadcast`, `scan`, ..), custom discovery mediums (`bluetooth`, `audio`, ..), awaitable native invokations and React hooks! > Also, this is a good example on how to use _Swift_ in a React Native - Native Module. [![react-native-google-nearby-messages](https://badge.fury.io/js/react-native-google-nearby-messages.svg)](https://badge.fury.io/js/react-native-google-nearby-messages) [![GitHub stars](https://img.shields.io/github/stars/mrousavy/react-native-google-nearby-messages.svg?style=social&label=Star&maxAge=259000)](https://GitHub.com/mrousavy/react-native-google-nearby-messages/stargazers/) [![GitHub followers](https://img.shields.io/github/followers/mrousavy.svg?style=social&label=Follow&maxAge=259000)](https://github.com/mrousavy?tab=followers) <a href='https://ko-fi.com/F1F8CLXG' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> ## Install > This packages uses React Native autolinking (> 0.60) ```sh npm i react-native-google-nearby-messages # for iOS cd ios && pod install && cd .. ``` > Note (iOS): Everytime you run `pod install` an entry called `Assets.car` is created in your **Build Phases** -> **[CP] Copy Pods Resources** which causes the build to fail. This is a known bug in the Google **NearbyMessages** pod. A workaround is to manually remove this file everytime you run `pod install`. See [#4 (comment)](https://github.com/mrousavy/react-native-google-nearby-messages/issues/4#issuecomment-649961499) for an automatic fix. Please [create a PR here](https://github.com/mrousavy/react-native-google-nearby-messages/pulls) if you found a better solution for this! ## Usage See the [example app](example/). ### iOS Setup > See: https://developers.google.com/nearby/messages/ios/get-started 1. Add bluetooth permissions (`NSBluetoothPeripheralUsageDescription`, `NSBluetoothAlwaysUsageDescription` for 'ble', and `NSMicrophoneUsageDescription` for 'audio') to `Info.plist` 2. Create your API Key at [the Google Developer Console](https://console.developers.google.com/flows/enableapi?apiid=copresence&keyType=CLIENT_SIDE_IOS&reusekey=true). 3. (Optionally): Add the [react-native-permissions](https://github.com/react-native-community/react-native-permissions) library to check if Bluetooth is available on the device (it's `'unavailable'` on iOS Simulators!) If it's `'unavailable'`, calls to subscribe or publish might crash the app (`EXC_BAD_ACCESS`) so only call if Bluetooth permission is `denied`, `granted` or `blocked`. This library will handle the permission checking for you when you call `publish()` or `subscribe()` for the first time. 4. Pass the generated API Key as a parameter using the `connect` function ### Android Setup > See: https://developers.google.com/nearby/messages/android/get-started 1. Create your API Key at [the Google Developer Console](https://console.developers.google.com/flows/enableapi?apiid=copresence&keyType=CLIENT_SIDE_ANDROID&reusekey=true). 2. Add your generated API Key and Permissions to your `AndroidManifest.xml`: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.sample.app" > <!-- For BLE/Bluetooth --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- For Audio --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <application ...> <meta-data android:name="com.google.android.nearby.messages.API_KEY" android:value="API_KEY" /> <activity> ... </activity> </application> </manifest> ``` 3. (Optionally): Call `checkBluetoothAvailability()` to ensure that Bluetooth capabilities are available on the current device. 4. Call `connect` without any key. ### Publishing ```ts import { connect, publish, addOnErrorListener } from 'react-native-google-nearby-messages'; const removeListener = addOnErrorListener((kind, message) => console.error(`${kind}: ${message}`)); const disconnect = await connect({ apiKey: GOOGLE_API_KEY }); const unpublish = await publish('hello !'); // later, e.g. in componentWillUnmount() removeListener(); unpublish(); disconnect(); ``` > Make sure to unpublish, disconnect and remove any listeners as they won't be removed automatically! I don't know if that's possible, if so, please create a Pull Request. ### Subscribing ```ts import { connect, subscribe, addOnErrorListener } from 'react-native-google-nearby-messages'; const removeListener = addOnErrorListener((kind, message) => console.error(`${kind}: ${message}`)); const disconnect = await connect({ apiKey: GOOGLE_API_KEY }); const unsubscribe = await subscribe( (m) => { console.log(`new message found: ${m}`); }, (m) => { console.log(`message lost: ${m}`); }); // later, e.g. in componentWillUnmount() removeListener(); unsubscribe(); disconnect(); ``` > Make sure to unpublish, disconnect and remove any listeners as they won't be removed automatically! I don't know if that's possible, if so, please create a Pull Request. ### Bluetooth Availability Check if the user has granted Bluetooth Permissions. This feature is experimental, and strongly differs between iOS and Android. ```ts import { checkBluetoothPermission } from 'react-native-google-nearby-messages'; const hasPermission = await checkBluetoothPermission(); ``` Check if bluetooth is available on this device. This feature is experimental, and strongly differs between iOS and Android. Make sure to use a library like **react-native-permissions** to check if Bluetooth is really available, otherwise your Application might crash with a `EXEC_BAD_ACCESS` error. See [troubleshooting](#troubleshooting) ```ts import { checkBluetoothAvailability } from 'react-native-google-nearby-messages'; const isBluetoothAvailable = await checkBluetoothAvailability(); ``` ### React Hooks This library also provides react hooks for common use cases. In case you're not familiar with hooks, please read the [hooks documentation](https://reactjs.org/docs/hooks-intro.html). When the component unmounts, the hooks automatically stop publishing, subscribing, remove error listeners and disconnect for you. You can also look into the [hooks source code](https://github.com/mrousavy/react-native-google-nearby-messages/blob/master/index.ts#L140-L259) and tweak them for your use case. Make sure to memoize the `NearbyConfig` object using `useMemo`, otherwise the hooks will fall into an infinite loop of re-renders because the config object gets re-created each time and therefore _has changed_. (See: [react useEffect's deps](https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects)) #### useNearbyPublication Publishes a message and returns a state which describes the Nearby API status. (e.g.: `connecting`, `published`, `error`, ...) ```ts export default function App() { const nearbyConfig = useMemo<NearbyConfig>(() => ({ apiKey: GOOGLE_API_KEY }), []); const nearbyStatus = useNearbyPublication(nearbyConfig, 'Hello from Nearby!'); // ... } ``` #### useNearbySubscription Subscribe to nearby messages and return a state for all messages in an array, as well as a state describing the Nearby API Status. (e.g.: `connecting`, `published`, `error`, ...) ```tsx export default function App() { const nearbyConfig = useMemo<NearbyConfig>(() => ({ apiKey: GOOGLE_API_KEY }), []); const { nearbyMessages, nearbyStatus } = useNearbySubscription(nearbyConfig); return ( <FlatList data={nearbyMessages} renderItem={({ item }) => <Text>{item}</Text>} /> ); } ``` #### useNearbySearch Search for a specific message using nearby messages. The `isNearby` local specifies whether the string `iPhone 11` could be found using the Nearby API, and the `nearbyStatus` local describes the current status of the Nearby API. (e.g.: `connecting`, `published`, `error`, ...) ```tsx export default function App() { const nearbyConfig = useMemo<NearbyConfig>(() => ({ apiKey: GOOGLE_API_KEY }), []); const { isNearby, nearbyStatus } = useNearbySearch(nearbyConfig, 'iPhone 11'); return ( <Text>{isNearby ? 'iPhone 11 is nearby!' : 'iPhone 11 is far, far away.'}</Text> ); } ``` #### useNearbyErrorCallback Subscribe to any errors emitted from the Nearby API. ```ts export default function App() { useNearbyErrorCallback((kind, message) => { console.log(`Nearby API Error: ${kind}: ${message}`) }); } ``` ## Troubleshooting If you're having any trouble getting the Nearby API working, please make sure you've read [the Troubleshooting Page](./TROUBLESHOOTING.md). If that doesn't help either, [create an issue](https://github.com/mrousavy/react-native-google-nearby-messages/issues). <a href='https://ko-fi.com/F1F8CLXG' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> ## Resources * [This medium article](https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03)