igloo
Docs / igloohome / BLE SDK / Fingerprint

Fingerprint

Enroll and remove fingerprints on Igloohome locks.


addFingerprint

Opens a BLE fingerprint registration window and returns a Flow of scan events. The lock requires 3 good reads to enroll a fingerprint (60-second timeout).

On successful enrollment, the SDK registers the fingerprint on the server. If server registration fails, the SDK automatically removes the fingerprint from lock hardware.

Signature

fun addFingerprint(
    deviceId: String,
    key: String,
    name: String,
    accessToken: String,
): Flow<FingerprintScanEvent>
func addFingerprint(
    deviceId: String,
    key: String,
    name: String,
    accessToken token: String
) async -> AsyncStream<FingerprintScanEvent>

Parameters

Name Type Required Description
deviceId String Yes Bluetooth device name of the lock.
key String Yes Guest key with ADD_FINGERPRINT permission.
name String Yes User-assigned name for the fingerprint.
accessToken String Yes Access token for server calls.

Return Type — FingerprintScanEvent

sealed class FingerprintScanEvent {
    /** Good read recorded. More reads needed. */
    data class ScanProgress(val attempt: Int, val total: Int) : FingerprintScanEvent()

    /** Bad read. Prompt user to try again. */
    class ScanError : FingerprintScanEvent()

    /** Enrollment completed and registered on server. */
    data class Completed(val accessId: String, val name: String) : FingerprintScanEvent()

    /** Enrollment failed. */
    data class Failed(val error: IglooHomeException) : FingerprintScanEvent()
}
enum FingerprintScanEvent {

    /// A scan was captured, the user should place their finger on the sensor again.
    case scanProgress(attempt: Int, total: Int)

    /// The lock failed to read the fingerprint, the enrollment is stopped.
    case scanError

    /// Enrollment succeeded and the access is registered on the Iglooworks server.
    case completed(accessId: String, name: String)

    /// Enrollment failed with the given error.
    case failed(error: any Error)
}
Event Description
ScanProgress(attempt, total) A good fingerprint scan. attempt = reads so far, total = 3.
ScanError Bad read — finger not positioned correctly. Prompt to retry.
Completed(accessId, name) All 3 reads successful. Fingerprint registered on server.
Failed(error) Enrollment failed (timeout, disconnect, etc.).

Example

try {
    sdk.addFingerprint(
        deviceId = "IGM4-XXXX",
        key = guestKey,
        name = "Right Thumb",
        accessToken = accessToken,
    ).collect { event ->
        when (event) {
            is FingerprintScanEvent.ScanProgress ->
                showProgress("Scan ${event.attempt}/${event.total}")
            is FingerprintScanEvent.ScanError ->
                showWarning("Bad read — try again")
            is FingerprintScanEvent.Completed ->
                showSuccess("Fingerprint enrolled: ${event.accessId}")
            is FingerprintScanEvent.Failed -> {
                when (event.error) {
                    is IglooHomeException.TimeoutException ->
                        showError("Timed out — place finger on sensor and try again")
                    is IglooHomeException.ConnectionException ->
                        showError("unexpected bluetooth connection issue")
                    else -> showError("Failed: ${event.error.message}")
                }
            }
        }
    }
} catch (e: IglooHomeException.BluetoothException) {
    showError("Please enable Bluetooth")
} catch (e: IglooHomeException) {
    showError("Fingerprint enrollment failed: ${e.message}")
}
let stream = await sdk.addFingerprint(
    deviceId: "IGM4-XXXX",
    key: guestKey,
    name: "Right Thumb",
    accessToken: accessToken)
var lastAttemp = 0, lastTotal = 0
for await event in stream {
    switch event {
    case let .scanProgress(attempt, total):
        showProgress(
            "Add Fingerprint",
            message: "Scanning \(attempt)/\(total) — place the finger on the reader",
            status: .warning)
    case .scanError:
        showProgress("Add Fingerprint", message: "Scan error, please try again", status: .failure)
    case let .completed(accessId, name):
        showProgress(
            "Add Fingerprint",
            message: "Fingerprint '\(name)' added. Access ID: \(accessId)",
            status: .success)
    case let .failed(error):
        showProgress("Add Fingerprint", message: error.localizedDescription, status: .failure)
    @unknown default:
        showProgress("Add Fingerprint", message: "Unknown event", status: .failure)
    }
}

Notes

  • The lock requires exactly 3 good reads to enroll a fingerprint.
  • Bad reads don't count toward the total — the user just tries again.
  • The entire flow times out after 60 seconds.
  • Errors are emitted as Failed events rather than thrown as exceptions.

deleteFingerprint

Removes a fingerprint from the lock and deletes the server record.

The SDK fetches the fingerprint UID from the server, removes it from lock hardware via BLE, then deletes the server record.

Signature

suspend fun deleteFingerprint(
    deviceId: String,
    key: String,
    accessId: String,
    accessToken: String,
)
func deleteFingerprint(
    deviceId: String,
    key: String,
    accessId: String,
    accessToken token: String
) async throws

Parameters

Name Type Required Description
deviceId String Yes Bluetooth device name of the lock.
key String Yes Guest key with DELETE_FINGERPRINT_UID permission.
accessId String Yes Server-assigned access ID of the fingerprint to delete.
accessToken String Yes Access token for server calls.

Error Codes

Exception Code Description
BluetoothException 708 Bluetooth is off or unavailable.
ConnectionException 12 Device disconnected during deletion.
TimeoutException 703 BLE operation exceeded the timeout.
ApiException varies Server deletion failed.

Example

try {
    sdk.deleteFingerprint(
        deviceId = "IGM4-XXXX",
        key = guestKey,
        accessId = "access-789",
        accessToken = accessToken,
    )
    showSuccess("Fingerprint removed")
} catch (e: IglooHomeException.ConnectionException) {
    showError("unexpected bluetooth connection issue")
} catch (e: IglooHomeException.TimeoutException) {
    showError("Timed out, try again")
} catch (e: IglooHomeException) {
    showError("Failed: ${e.message}")
}
do {
    try await sdk.deleteFingerprint(
        deviceId: "IGM4-XXXX",
        key: guestKey,
        accessId: "access-789",
        accessToken: accessToken)
    showSuccess(message: "Fingerprint removed")
} catch {
    showError(message: "Failed: \(error.localizedDescription)")
}

Notes

  • Server deletion retries up to 3 times with 1-second delays.
  • LockUidNotFoundException (980) during BLE delete is non-fatal — server record is still removed.