DP3T SDK bindings for React Native.
Pre-alpha. Requires some manual setup to work. Not tested yet. Can change without notice.
The iOS SDK and Android SDK themselves are in alpha state.
This project is bootstraped from bob, see implementation notes.
yarn add react-native-dp3t-sdk@alpha
This lib does not work on emulators or simulators, because Bluetooth. Run on physical devices.
If you use Fiber to display the Android SDK database, note that the ephID column is always blank. This is because ephIDs are encrypted BLOBs, they are not missing.
Customize the tracing notification as in the Android SDK
You have to make changes in build.gradle
:
minSdkVersion
to 23 or above, as the Android DP3T SDK dos not support lower versions.compileSdkVersion
to 29 or above, to fulfill the requirement forandroid:foregroundServiceType
in Android Q (set by the Android DP3T SDK).
The lib automatically sets the android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
permission.
The lib also ask the user to add your app to the battery optimization whitelist for you when you call Dp3t.init()
.
The Play Store usually prohibits this, so you need to make sure the Play Store filing explains why this is necessary. This may only be necessary until the Android SDK uses official Google DP3T support, in which case we will adapt the permissions & warnings in this section.
Minimum iOS version is 11 for DP3T iOS SDK, so you need to change the verison to (at least) 11.0 in your iOS Podfile.
If you are not in v0.62, you have to add the react-native-swift package and run react-native swiftify
and run pod install
again, because this native module (and the DP3T iOS SDK) use Swift.
If you are in v0.62 you should be fine just using the module.
Add bluetooth capabilities to your Info.plist file.
Add background fetch configuration to your Info.plist file.
Until we have a way of initializing the background sync manager on iOS, you need to add this line to your Podfile:
pod 'DP3TSDK', :git => "https://github.com/fmauquie/dp3t-sdk-ios.git", :branch => 'develop'
This implementation does not yet support requesting the permissions to use Bluetooth in iOS.
import * as Dp3t from 'react-native-dp3t-sdk';
// or
import { useDp3tStatus } from 'react-native-dp3t-sdk';
You need to initialize the SDK before calling most methods. You have 2 ways:
Initialize the SDK with the GitHub discovery service.
The discovery service is a JSON file on GitHub:
- for production: https://github.com/DP-3T/dp3t-discovery/blob/master/discovery.json
- for dev: https://github.com/DP-3T/dp3t-discovery/blob/master/discovery_dev.json
Params:
backendAppId
: TheappId
in the discovery servicepublicKeyBase64
: The public key of the service. Necessary for sync in Android.dev
Should use the dev or production service ? Defaults tofalse
(production)
initManually(backendAppId: string, reportBaseUrl: string, bucketBaseUrl: string, publicKeyBase64: string): Promise<void>
Initialize the SDK by passing the backend URLs.
Params:
backendAppId
: Unique ID for the backend, used internally by the SDK to reset the sync caches when it changes (I think)reportBaseUrl
: Report URL for the backend (should be provided by your backend provider)bucketBaseUrl
: Bucket URL for the backend (should be provided by your backend provider)publicKeyBase64
: The public key of the service. Necessary for sync in Android.
Is the SDK initialized ?
Use this to know if you can call the main methods or if you need to call the init*
methods first.
Resolves promise with true
when the SDK is initialized
Start tracing.
The phone will start advertising EphIDs with Bluetooth.
The phone will start listening to EphIDs from other devices.
This will only work if all Bluetooth and permission errors have been managed (see TracingStatus.errors
below)
Stop tracing.
This will stop advertising EphIDs and stop collecting them.
Fetch the status of the SDK.
Resolves the promise with the current TracingStatus
(see below)
This will throw an error if the SDK has not been initialized.
Report the user as infected.
Use this when the user has been tested positive to the virus.
ALPHA WARNING there are 2 ways in the SDKs to send the authentication code. This implementation assumes HTTP auth method until more info is known.
onset
: The date when the user was tested positiveauth
: The code given by the doctor to the user for authentication, passed depending on how the server operates. Pass{ autorization: '<code>' }
to use a HTTP authorization header, pass{ json: '<code>' }
to use a JSON payload.
Force a sync.
The SDKs sync the known cases periodically. You can force a sync now.
Resolves promise with true
if the sync was forced,
false
if a sync was already in progress.
Clear all data and reset the service.
You will need to call a init*
method again.
Listen to status changes.
You certainly should use useDp3tStatus()
instead.
Do not ever forget to unregister the listener on unmount with subscription.remove():
useEffect(() => {
const subscription = addStatusUpdatedListener(setStatus);
return () => subscription.remove();
}, []);
Params:
listener
The listener will be called on each status change with the new status.
Requests missing permissions.
This only does something on Android. On iOS the permissions are requested by the SDK for us.
This is still important to monitor the permission error on iOS: if the user refuses to grant them we need to show them a nice message with some explanations.
Resolves the promise with a PermissionStatus on Android (this is a string: 'granted' | 'denied' | 'never_ask_again')
Resolves the promise with 'ios' on iOS
Params:
rationale
The texts to show on some Android devices (on iOS they go in Infos.plist, check iOS specific setup instructions).
Listens to the status of the DP3T service.
Usage:
const [status, refreshStatus] = useDp3tStatus();
status
is:
null
if the status is loading from the SDK (briefly on mount)false
if the SDK is not initialized (call init*() methods)- the
TracingStatus
in normal operation
refreshStatus
is a function you can call to force a status refresh from the SDK.
You usually do not need to use it (the SDKs are pretty good at keeping this up-to-date),
but it is useful in the following situations:
- You just called
requestPermissions()
(the status will not update on permissions grant) - To give the user a way to make sure the status is the lastest available
Status of the tracing SDK
Attributes:
tracingState: TracingState
: string that can take the following values:started
: SDK is exchanging EphIDs with people aroundstopped
: SDK is not started, but can beerror
: SDK is not started, and there are errors that prevent SDK from starting (seeerrors
attribute)
numberOfHandshakes: number
: This is the number of signals your phone received from other phones. You may need to manually refresh the status to see this value change.numberOfContacts: number
: This is the number of unique IDs your phone saw. This will always be lower than the number of handshakes. This is only updated on sync: do not consider this information real-time. As of 2020-04-27 this stays 0 in iOS, no idea why.healthStatus: HealthStatus
: string representing the health status of the user. Values can be:healthy
: The user has not been tested positive and has not contacted anyone that has been. There as no reason to believe that they are at risk as far as tracking is concernedexposed
: The phone has made a handshake with a contact that was tested positive. You will see the list of these contacts inmatchedContacts
infected
: The user has declared they have been tested positive usingsendIAmInfected()
.
nativeStatusArg?: Object
: In iOS the health status can have an argument. It is provided there. See iOS SDK for details.lastSyncDate: Date | null
: Last time the SDK synced with the backend server.null
if never syncederrors: Dp3TError[]
: Array of strings that represent the possible error conditions in the SDK. On iOS there is only one error at a time. On Android you can have the same string multiple times (they correspond to differentnativeErrors
). Possible values are:bluetoothDisabled
: Bluetooth is disabled on device. Ask user to enable bluetooth (and refresh status).permissionMissing
: Missing permissions. On iOS this is bluetooth permission, on Android this is both location permission and battery optimization disabling. Call requestPermissions() to fix for Android, display an error in iOS.sync
: Error while syncing. SeenativeErrors
for more information.other
: Other error (checknativeErrors
for more information) Only in iOS
nativeErrors: string[]
: Native errors that corresponds to the error above. These are different in iOS and Android, see the individual SDKs for more information. On iOS, there is only one error at a time.nativeErrorArg?: Object
: On iOS, the error can have an argument. It is there. See iOS SDK for details.exposedDays: ExposedDay[]
: The days you were exposed (see type definition below). The array always carry a value, but it will only be filled ifhealthStatus === 'exposed'
Information about an exposition to an infected contact.
Attributes:
id: number
: Some internal unique ID. Can not be used to identify a contact, but can serve as a Reactkey
exposedDate: Date
: Date we saw this contact. This is set to a start of day, e.g. midnight GMTreportDate: Date
: Date the contact reported themselves as exposed.
MIT
Wix incubator is building a RN lib from scratch (they don't use DP3T SDK)