ExpoでReact-nativeを使用して、Androidに生体認証(faceID /指紋)を実装しようとしています。
LocalAuthentication.authenticateAsync()
関数を使用すると、ユーザーは自分のバイオメトリで認証できます。ただし、失敗した場合、ユーザーは生体認証をもう一度押す必要があります。
だから私はrecursifまたはdowhileループで少しトリックを試しましたが、結果は奇妙です:
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);
}
};
このコードでは、ユーザーが生体認証に失敗した場合、「else」を無限に渡します...
だから私はAndroidでそれをどのように処理するのか疑問に思いました。
Expoは、ローカル認証の結果に「エラー」キーを提供します。ハードウェアエラーを処理しないために、私はこれを使用しました:
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;
}
}
変数を使用して手動で処理できます。まず、コンストラクター内またはクラスのプロパティとして変数retryCount
を作成し、各関数でアクセスできるようにします。
constructor(props) {
super(props);
this.retryCount = 3;
}
retryCount
関数を呼び出す前に、scanFingerPrint
の値を設定してください。
this.retryCount = 3; //number of attempts you want to provide
次に、無限ループを防ぐために、以下のように関数を変更します。
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);
}
};
試行のために関数変数を渡すことができます。
これを見て、
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);
}
};
他に何も変更する必要はありません。初めての関数呼び出しをイベントにしないでください。