Biometrics
Biometrics wraps expo-local-authentication: whether the device can authenticate the person in
front of it, and the system prompt that does it.
import { Biometrics } from '@ng-native/expo';
inject(Biometrics)Install
npx expo install expo-local-authenticationimport { Biometrics } from '@ng-native/expo/biometrics';The smallest thing that works
import { Component, inject } from '@angular/core';
import { Biometrics } from '@ng-native/expo/biometrics';
@Component({
selector: 'app-wallet',
template: '<pressable (press)="unlock()"><text>Unlock</text></pressable>',
})
export class Wallet {
private readonly biometrics = inject(Biometrics);
protected async unlock(): Promise<void> {
if (!(await this.biometrics.available())) return;
const result = await this.biometrics.authenticate('Unlock your wallet');
if (result.success) this.reveal();
}
private reveal(): void {}
}Checking and asking
available()resolves to whether there is a sensor and something enrolled on it - whether asking can succeed at all. Check it before showing a "Use Face ID" button.kinds()resolves to the kinds the device has -'fingerprint','face','iris'- so a button can say "Use Face ID" rather than the generic "Use biometrics".authenticate(message, options)shows the system prompt withmessageas the reason, and resolves to{ success: true }or{ success: false, error }, whereerroris the platform's own reason:'user_cancel','lockout','not_enrolled'and so on.optionsisexpo-local-authentication's ownLocalAuthenticationOptions(minuspromptMessage, whichmessagesupplies), for things likedisableDeviceFallbackandcancelLabel.
Face ID needs a usage string
Face ID ends the app the first time it is asked for without one. Add to Info.plist:
<key>NSFaceIDUsageDescription</key>
<string>Allow this app to use Face ID</string>The module's config plugin writes this automatically. Android's USE_BIOMETRIC and
USE_FINGERPRINT permissions are added automatically too - there is no separate ask-at-runtime
permission dialog on either platform; authenticate() itself shows the system UI.
Without the module
authenticate() fails rather than passes without the module - { success: false, error: 'not_available' } - unlike every other service here, which falls back to reporting nothing. A
lock that opens when its sensor is missing is not a lock. available() resolves to false and
kinds() to an empty list.
Reference
Biometricsservice@ng-native/expoimport { Biometrics } from '@ng-native/expo';Methods
available(): Promise<boolean>Whether there is a sensor and something enrolled on it: whether asking can succeed.
kinds(): Promise<BiometricKind[]>The kinds the device has, for a button that says "Use Face ID" rather than "Use biometrics".
authenticate(message: string, options: AuthenticateOptions = {}): Promise<AuthenticationResult>Show the system prompt. Without the module this fails rather than passes: a lock that opens when its sensor is missing is not a lock.