Android Biometric
Authenticate Instantly with Android Biometrics
Securely authenticate users on Android devices using fingerprint, facial recognition, or other biometric methods with the Median Android Biometric Authentication Plugin. This plugin uses the Median JavaScript Bridge to store and retrieve encrypted secrets, enabling biometric login experiences.
The plugin supports both:
- Strong Biometrics: Fingerprint sensors, infrared facial recognition (hardware-backed)
- Weak Biometrics: Face unlock via standard camera (software-only)
As the developer, you define the minimum biometric level required (strong or weak) depending on your app’s security needs.
How it works
- Check Biometric Availability
First, check whether biometric authentication data is available and biometrics are supported for the device (older models or MDM configurations may disable the support). - Save Login Secret
After a user logs in and biometric authentication is available, the website can save a secret using the plugin. The secret is stored in the iOS Keychain, which uses cryptographic hardware to ensure it cannot be retrieved without biometric authentication. Saving the secret does not require user interaction. - Retrieve Saved Secret
On future visits, if a saved secret is available, the site can prompt the user to authenticate via Android Biometrics. If authentication succeeds, the secret is returned via the JavaScript callback. If it fails, an error is returned. - Use Secret to Log In
Once the secret is recovered, you can either use it to directly login the user or populate the login form on you web app.
Developer Demo
Display our demo page in your app with the Face ID / Touch ID Android Biometric Native Plugin active to test during development https://median.dev/auth/
Implementation Guide
This guide assumes a working publicly-accessible website (or test site) with a username and password login system.
Saving a Secret After Login
After a user successfully logs in to your website with their username and password, check to see the device has biometric capabilities available. If biometrics are available then seamlessly save a secret for future retrieval. The secret must be a single string, and can be a combination of the username and password or an authentication token. You may specify a minimum biometric level to support, either strong
or weak
.
↔️Median JavaScript Bridge
For example, you may embed this JavaScript into your post-login page:
var username = 'andy' var password = 'password'; median.auth.status({'callbackFunction': median_status_afterlogin}); // returns promise function median_status_afterlogin(data) { if (data && data.hasTouchId) { var secret = JSON.stringify({ username: username, password: password }); median.auth.save({ 'secret': secret, 'minimumAndroidBiometric': 'strong' }); } }
Tip: Some JS Bridge commands return promises. They are usually declared as such through a comment to help you identify them. Learn More.
In this example, we have saved the username and password as the secret. You may choose to save an authentication token instead. We have specified the minimumAndroidBiometric
as strong
which is the default biometric level.
Checking for a Saved Secret on Login Page
↔️Median JavaScript Bridge
On the login page, you will need to know whether or not to prompt for biometric login. Start by getting the status:
median.auth.status({'callbackFunction': median_status_beforelogin}); // returns promise function median_status_beforelogin(data) { if (data && data.hasTouchId && data.hasSecret) { // Prompt the user to use biometrics to log in median.auth.get({'callbackFunction': median_secret_callback}); } } function median_secret_callback(data) { if (data && data.success && data.secret) { var credentials = JSON.parse(data.secret); var username = credentials.username; var password = credentials.password; // Use username and password to do login here, // e.g. an http post or ajax request } else { // Allow manual entry } }
Once the
median_secret_callback
function is called with the previously saved secret, it should perform a request to log in the user. If the credentials are incorrect, you should delete the secret and allow manual login by running the function:// delete secret if credentials are incorrect median.auth.delete({'callbackFunction': CALLBACK});
Median JavaScript Bridge Reference
Check Biometric Availability
↔️Median JavaScript Bridge
Run the JavaScript function:
median.auth.status({ 'minimumAndroidBiometric': 'strong' | 'weak', // optional, default is 'strong' 'callbackFunction': CALLBACK // optional if callback is used rather than promise });
The app will return a promise, or if provided execute CALLBACK, with an object parameter containing the fields:
hasTouchId
:true
orfalse
. Set totrue
on Android devices with fingerprints enrolled.hasSecret
:true
orfalse
Save a Secret
Typically you will want to first check that biometrics are available via the status function above and then save the secret.
↔️Median JavaScript Bridge
Run the JavaScript function:
median.auth.save({ 'secret': secret, 'minimumAndroidBiometric': 'strong' | 'weak', // optional, default is 'strong' 'callbackFunction': CALLBACK // optional if callback is used rather than promise });
The app will return a promise, or if provided execute CALLBACK, with an object with a
success
field
Retrieving a Secret
↔️Median JavaScript Bridge
Run the JavaScript function:
median.auth.get({ 'callbackFunction': CALLBACK, // optional if callback is used rather than promise 'minimumAndroidBiometric': 'strong' | 'weak', // optional, default is 'strong' 'prompt': 'PROMPT', 'callbackOnCancel': INTEGER // optional });
Prompt is only available for iOS and it has been included above to ensure cross-platform compatibility. The app will return a promise, or if provided execute CALLBACK, with an object parameter containing the fields:
success
: true or falseerror
: provided success is false (see error codes below)secret
: the previously stored secret
callbackOnCancel
is optional. If set to1
and acallbackFunction
has been provided, when the user cancels the authentication the callback function will be invoked withsuccess=false
,error=userCanceled
. IfcallbackOnCancel
is not set (or set to 0), the callback will not be run on cancel.
Delete a Secret
↔️Median JavaScript Bridge
Run the JavaScript function:
median.auth.delete({ 'callbackFunction': CALLBACK // optional if callback is used rather than promise });
The app will return a promise, or if provided execute CALLBACK, with an object parameter containing the fields:
success
: true or falseerror
: provided if success is false
Possible error values
In general, you will only need to handle authenticationFailed in the "get secret" request.
duplicateItem
: Secret already existsitemNotFound
: No secret savedauthenticationFailed
: Biometric check failedgenericError
: Unexpected failureuserCanceled
: User canceled the auth promptunimplemented
: Plugin not supported
Testing Android Biometric Integration
We recommend testing on physical devices to confirm the flow is working as expected for devices with Android Biometric support, as well as older models or more restricted device configurations.
Additionally, you can also test the integration using the Appetize Simulators.
- Open the demo page in the simulator
- Click the Fingerprint ID Button (as shown below) to enable biometrics support in the simulator
- Log in with credentials
- Return to the demo page and use the Login with Biometrics button without having to provide username and password again

Appetize - Fingerprint ID Button
Whitelist Domains for Plugin Access
By default, any page loaded in your app will be able to use Median JavaScript Bridge to retrieve secrets. If you are allowing any domains you do not control to be loaded within your app (see Link Handling), we strongly recommend whitelisting only certain domains.
To do so, go to the Native Plugins tab in the Median App Studio, click Settings for the Face ID/TouchID Android Biometrics plugin and add your whitelisted URLs as shown below.
Regular expressions are supported to allow wildcards in the URL.

Whitelisting URLs for Access
Updated about 2 months ago