Currently, when I kill the App on the first-time keychain persist data perfectly. However, on the second time, on App killing keychain reset credentials. Here is my code:
componentDidMount() { AppState.addEventListener('change', this._handleAppStateChange); Keychain.getGenericPassword() .then((credentials) => { console.log(credentials.username,'Credentials Log') if (credentials.username === '' || credentials.username === undefined) { this.setState({isKeyClear:true,isTouchShow:false}) } else { this.setState({isKeyClear:false,isTouchShow:true}); // this.clickTouchID(); } }) .catch(err => { console.log("err: ", err); }); }
Here, i checked the Touch Id or face Id support:
clickTouchID = () => { console.log('Click'); TouchID.isSupported() .then(biometryType => { if(biometryType){ if (biometryType === 'TouchID') { // Touch ID is supported on iOS // this.setCredentials(username, password); this.getCredentials(); } else if (biometryType === 'FaceID') { // Face ID is supported on iOS this.getCredentials(); } else if (biometryType === true) { console.log(biometryType,'Android'); // Touch ID is supported on Android this.getCredentials(); } } else{ console.log('Not Supported'); } }) .catch(error => { console.log('Users device does not support Touch ID (or Face ID)', error); this.devicesSupportedAlert(); // User's device does not support Touch ID (or Face ID) // This case is also triggered if users have not enabled Touch ID on their device }); }
This method store credentials in keychain:
setCredentials = async (username, password) => { return new Promise((resolve, reject) => { // Store the credentials Keychain.setGenericPassword(username, password, {accessible: Keychain.ACCESSIBLE.ALWAYS}) .then(resp => { console.log(resp,'Setcredentials Response'); // this.getCredentials(); resolve(true) }) .catch(err => { console.log("err: Detail", err); reject(err); }); }); }
This method gets credentials in keychain but conditions first check if data exist or not.
getCredentials = async () => { return new Promise((resolve, reject) => { Keychain.getGenericPassword() .then((credentials) => { if (credentials.username === '' || credentials.username === undefined) { if(isAndroid){ this.setState({isKeyClear:true,isTouchShow:false}) } console.log('No credentials stored'); resolve(credentials); } else { if(isAndroid){ this.setState({isKeyClear:false,isTouchShow:true}) } console.log('Credentials successfully loaded for user'+ credentials.username); // If Touch ID authentication is successful, call the `login` api TouchID.authenticate() .then(() => { // If Touch ID authentication is successful, call the `login` api this.setState({bioState:true}); let userObj = { Isemail:credentials.username, Ispassword:credentials.password } this.onPressLogin(userObj) }) .catch(error => { console.log("error: ", error); reject(error); }) } }) .catch(err => { console.log("err: ", err); reject(err); }); }); } _handleAppStateChange = (nextAppState) => { if(isAndroid){ if (nextAppState === 'background' || nextAppState === 'active') { this.clickTouchID(); console.log('the app is closed Android'); } } else if(nextAppState === 'inactive') { console.log('the app is closed IOS'); } }