Reputation: 342
I'm trying to implement a biometric authentication (faceID / fingerprint) on Android using React-native with Expo.
Using the LocalAuthentication.authenticateAsync()
function, the user is able to authenticate with his biometry. But if it fail, the user have to press the biometric authentication again.
So i tried a little trick with a recursif or do while loop but the result is strange :
const scanFingerPrint = async () => {
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
} catch (e) {
console.log(e);
}
};
With this code, if the user fail the biometric authentication, it will pass in the "else" infinitly...
So I was wondering how to handle that on android.
Upvotes: 5
Views: 2593
Reputation: 342
Expo provide an "error" key on the results of the local authentication. To not handle an hardware error i used this :
if (!results.success) {
switch (results.error) {
case "lockout":
setLocked(true);
break;
case "authentication_failed" || "too_fast":
ShakeAnimation(animatedValueModal);
await scanBiometric();
break;
case "user_cancel" :
break;
default:
ShakeAnimation(animatedValueModal);
break;
}
}
Upvotes: 0
Reputation: 4961
You can pass function variable for attempts.
see this,
const scanFingerPrint = async (remainingAttempts = 5) => { // you can change 5 as per your choice
try {
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential().then(credentials =>
onScan(credentials)
);
} else {
ShakeAnimation(animatedValueModal);
if (remainingAttempts) {
remainingAttempts--;
scanFingerPrint(remainingAttempts);
} else {
alert("You have exceeded max scan limit.");
}
}
} catch (e) {
console.log(e);
}
};
and you do not need to change anything else. not event your first time function call.
Upvotes: 0
Reputation: 2451
You can handle it manually using a variable.
First create variable retryCount
inside constructor or as a property of class so that it is accessible in each function.
constructor(props) {
super(props);
this.retryCount = 3;
}
set the value of retryCount
before calling scanFingerPrint
function.
this.retryCount = 3; //number of attempts you want to provide
Now modify function like below to prevent infinite loop:
const scanFingerPrint = async () => {
try {
if (this.retryCount <= 0){
//exceeded the number of attempts..try again after a minute
} else{
this.retryCount--;
const results = await DeviceService.biometricAuthentication();
if (results.success) {
SecureStoreService.getCredential()
.then(credentials => onScan(credentials));
} else {
ShakeAnimation(animatedValueModal);
return scanFingerPrint();
}
}
} catch (e) {
console.log(e);
}
};
Upvotes: 0