Get the user id configured for the device (iCloud recordID for iOS, email of a device account for android)
When implementing a mobile application you want to provide your users as much functionality as you can without having them sign up. After all, Every Step Costs You 20% of Users.
Sign up may very well be the step where most of your potential users are lost.
Now imagine you could get a unique identifier that worked across all of the devices of the user. You could even have in-app purchases that are shared across devices without having to sign-up.
This library aims to provide all of the above in the simplest way possible:
Note: If you are already using firebase authentication see the FAQ for instructions on how to upgrade its anonymous authentication
Note: If you are considering using Sign In with Apple see the FAQ section first
1. Install the library
yarn add react-native-user-identity
2. Run pod install
cd ios
pod install
3. (OPTIONAL STEP: REQUIRED FOR OLD DEPENDENCY VERSIONS AND SDKs) Configure swift support for your iOS project
This configures your iOS project to use the module correctly since the library contains swift code (see the official react native documentation for more information)
Note: If your iOS project is alredy using swift files and you have a bridging header you may skip this step.
a. Create a swift file with any name in the root of your project:
b. Select "Create Bridging Header" when Xcode asks for it:
4. Build the project
You should be able to build the project now.
Note: The package functionality will not work until you follow the steps of the next section
Note 2: If you are having trouble building your project after executing the example try opening XCode preferences, select the "Locations" tab and set DerivedData to be a relative folder.
Nothing to configure.
(Screenshots taken with Xcode 11.x)
Enable the CloudKit option of the iCloud capability
(OPTIONAL STEP: REQUIRED FOR OLD IDE CONFIGURATIONS) Add a container and name it exactly as the bundle identifier of the application:
Verify all of the following:
import RNUserIdentity, { ICLOUD_ACCESS_ERROR } from 'react-native-user-identity'
fetchUserIdentity = async () => {
try {
const result = await RNUserIdentity.getUserId()
if (result === null) {
alert('User canceled UI flow')
}
} catch(error) {
if (error === ICLOUD_ACCESS_ERROR) {
alert('Please set up an iCloud account in settings')
}
}
}
On iOS fetching the id does not require user intervention. However, it might be useful in some instances to have the user confirm the action.
You may send a truthy value for the iosUserConfirmation parameter for this to happen.
The following code:
RNUserIdentity.getUserId({
iosUserConfirmation: true
})
Presents this dialog:
The resolved value will be null if the user dismisses the dialog
You can also configure the text shown to the user:
RNUserIdentity.getUserId({
iosUserConfirmation: {
title: 'Confirm sign in',
message: 'Sign in requires user confirmation',
signInButtonText: 'Confirm',
cancelButtonText: 'Back'
}
})
There is an optional parameter you can send:
The following code:
RNUserIdentity.getUserId({
androidAccountSelectionMessage: 'Choose an account for testing:'
})
Presents this modal (the modal styles are OS dependant):
Use yarn to install the dependencies. Npm installs local dependencies using symbolic links and the react native packager does not support this.
The CloudKit framework prevents applications from accesing the user email for privacy purposes.
Sign in with Apple requires the user to complete a full sign in flow.
The point of using this package is to skip entirely this flow so your users can directly start using your application
Make sure you followed all of the steps in the installation and configuration section and pay attention to the verification note at the end of the configuration section
You could use the same principle behind Firebase anonymous authentication but most likely you will run into the same limitations: Identities are associated to app installations (or devices in the best case scenario).
Once a user uninstalls the app, signs out or changes devices the user identity is lost.
If you are already using firebase authentication you want to incorporate react-native-user-identity as another option for the user to sign in (or maybe you just want to replace anonymous authentication).
You should then:
const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp()
exports.tokenFromUID = functions.https.onCall( async (data, context) => {
const { uid } = data
try {
return await admin.auth().createCustomToken(uid)
} catch(error) {
console.log('Error creating custom token: ', error)
throw new functions.https.HttpsError('internal', error ? error.message : '')
}
})
With this cloud function you also need to configure permissions for your firebase instance. See [this section of the firebase documentation](https://firebase.google.com/docs/auth/admin/create-custom-tokens#troubleshooting) for details
<br><br>
2. Sign in with the custom token on your app<br> Assuming you are using [rnfirebase](https://rnfirebase.io/):
Replace this:
```javascript
import auth from '@react-native-firebase/auth'
const userCredential = await auth().signInAnonymously()
With this:
import auth from '@react-native-firebase/auth'
import functions from '@react-native-firebase/functions'
import RNUserIdentity from 'react-native-user-identity'
// get uid for user...
const uid = await RNUserIdentity.getUserId()
if (uid != null) {
// Server call (a firebase cloud function in this case)
const tokenResponse = await functions().httpsCallable('tokenFromUID')({ uid })
const userCredential = await auth().signInWithCustomToken(tokenResponse.data)
}