Expo Local Authentication not working for non-Biometric devices - android

I am using expo local authentication in an expo project and it works perfectly with IOS/Android, But for older android devices that doesn't have Face/Touch ID its not possible to use local authentication and gives this error:
Object {
"error": "not_available",
"message": "Biometric hardware unavailable",
"success": false,
}
I tested in expo SDK 38 and 39, with expo-local-authentication version 9.2.0 and 9.3.0 .
Any help how can i use Pin/Pattern for older non-biometric devices?

Since the Local authentication package only does biometric, it won't just do device pin without having biometric hardware.
to guard against older devices, you simply use the following methods to disable the biometric code.
LocalAuthentication.hasHardwareAsync();
and
LocalAuthentication.isEnrolledAsync()
both return a promise, so you need to await for them.
if (await LocalAuthentication.isEnrolledAsync() && await LocalAuthentication.isEnrolledAsync()) {
//do biometric auth
} else {
// implement your own password or use another package for device pin.
}

Related

Network Error on calling API in React Native from few specific Android devices

We've integrated a very simple test apk that calls a HTTPS API running on IIS into a react native application. The issue is it throws "Network Error" when trying to make API calls from Motorola C Plus phone running Android 7 & Samsung Galaxy J2.
Sample Code
var dataToSend = {
Name: name,
Email: userEmail,
Password: password,
Mobile: mobile,
};
try {
alert('Entered inside of try block');
const userRes = await axios.post(
'https://api.in/api/Account/CustomerRegistration',
dataToSend,
);
//Code does not display this alert
alert('after axios request');
alert(JSON.stringify(userRes.data));
} catch (error) {
alert(error); // request failed with status code 400
console.log('error', error);
}
The app runs well on localhost as well as other android phones. Have tested SSL certificate and it looks okay. Completely clueless regarding the issue. Any help would be appreciated. Would be happy to share code if required.

Why does preflight fail on newer Android devices but not older devices and desktop?

I am using the axios package to send API requests from my app to my backend
The backend is built with Laravel and is a simple rest API
If I run the Ionic app on desktop using ionic serve it works fine
If I build an APK and install the app:
on an Android device with version 8 or below it works fine
on an Android device with version 9 or above the preflight checks keep failing
(This is using the remote devices feature by Chrome to inspect requests from the app)
Initially, the requests wouldn't even send and it would error out before then and so I setup my network security configuration for Android and that removed the initial error but now it keeps failing on preflight
My suspcion is that it might be related to the fact that the requests on the app are being sent from http://localhost but I'm not sure how to resolve this. Can you force it to use an SSL? If so, how?
My CORS setup for Laravel is more leniant than the default CORS config that Laravel ships with:
return [
'paths' => ['*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
The issue was related to SSL/TLS pinning which axios doesn't deal with as per this comment.
The Ionic Native HTTP plugin handles the pinning natively and that worked for but of course it makes use of Cordova which isn't available on your non-mobile devices.
There were two potential solutions:
Implement SSL/TLS pinning natively
Create a service/factory which determines whether we want to use axios or the native plugin
I opted for #2 - if you want information regarding #1, see this answer.
The following method for me determines which HTTP wrapper to use:
static makeRequest() {
return isPlatform('cordova') ? cordovaHttpService : axiosHttpService;
}
Of course, that can be amended with each specific case.

XHR request to Firebase Functions stays hanging on Samsung Internet Browser 14

Our app uses the Firestore and Firebase Functions. To save an order, we call a https callable Firebase Function like this:
try {
const setMealplanOrder = fn.httpsCallable("setMealplanOrder");
await setMealplanOrder(newOrder);
return true;
} catch (error) {
console.log("🚀 ~ file: saveOrder.tsx ~ line 158 ~ save ~ error", error)
Sentry.captureMessage("Error saving order, possibly on Android?" + error);
}
It works and has worked on all devices, until a few days old Samsung update to Android 11 and Samsung internet 14. Now, the XHR request from await setMealplanOrder(newOrder) is just stuck. The console is empty, with no errors.
Any idea what could it be? Or how to debug this?
Additional notes:
Interestingly, when I connect the phone to the app on a localhost, it works perfectly.
When I try to fire the same request from a new clean app, it works. So the issue is probably caused in a combination with something else in the app.
Solved: Firebase version issue! The issue was in firebase-messaging-sw.js Service Worker, which we use for Firebase Cloud Messaging (push-notification). The version of the service worker was outdated.
// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/7.17.2/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/7.17.2/firebase-messaging.js')
...
After updating both npm i firebase#latest and changing the version in the importScripts to 8.4.3, it works as it should.

Ionic/Angular + Firebase with emulator on Android device = auth/network-request-failed

I have to improve existing Ionic app using firebase as auth method for users login.
For my purpose i cannot touch existing list of previously registered users in production firebase app, I have to create new list locally using firebase emulator.
After adding and setup local auth & DB emulator extensions, I have added this into app.module.ts:
if (window.location.hostname === 'localhost') {
firebase.auth().useEmulator('http://localhost:9099');
}
After continuing with adding new UI and logical features, using a web browser to test my work, I switch to the Android platform. After running the app and executing
firebase.auth().signInWithEmailAndPassword(email, password);
I got the following error:
{
"code": "auth/network-request-failed",
"message": "A network error (such as timeout, interrupted connection, or unreachable host) has occurred."
}
It worked fine in the browser, but not on real device.
Whereas on Android device
window.location.hostname === 'localhost
this will be executed
firebase.auth().useEmulator('http://localhost:9099');
so Firebase searching auth service on device on port 9099, that not exists, and produce such error.
To fix this just run in terminal
adb reverse tcp:9099 tcp:9099

Ionic with React and google auth: idToken is truncated in android

I'm using Ionic with React and #codetrix-studio's capacitor-google-auth plugin to enable google auth. The processed idToken has different lengths when comparing Web to Android environments.
When running in the web browser I'm getting 1224 chars and everything works just fine. But when running android I'm only getting 1122 chars. Also I'm not getting anything out of the accessToken.
Can anyone provide some hits on how to solve this?
I'm getting the token like so:
async signIn(): Promise<void> {
const result: any = await Plugins.GoogleAuth.signIn();
if (result) {
let token = result.authentication.idToken;
this.setToastMsg(token.length + "");
}
}
This is triggered from a simple button:
<IonButton onClick={() => this.signIn2()} >Login with Google</IonButton>
Turns out the token provided by google for the android api is actually smaller. So everything is ok.

Categories

Resources