fix(rebreak-native): don't crash on old dev-clients missing ExpoLocalAuthentication
appLock.ts is imported from the root layout, so an unguarded top-level
`import * as LocalAuthentication from 'expo-local-authentication'` crashes the
whole app at launch on a dev-client built before the dependency was added
("Cannot find native module 'ExpoLocalAuthentication'"). Load it via a guarded
require; if absent → app lock reports `available: false`, everything else runs.
Real builds (EAS / fresh prebuild) ship the module and work normally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aa9466aa92
commit
4a17c7942d
@ -1,6 +1,21 @@
|
||||
import { create } from 'zustand';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import * as LocalAuthentication from 'expo-local-authentication';
|
||||
|
||||
// expo-local-authentication ist ein NATIVE-Modul. In einem Dev-Client, der noch
|
||||
// VOR dem Hinzufügen dieser Dependency gebaut wurde, fehlt der native Teil →
|
||||
// `require()` wirft "Cannot find native module 'ExpoLocalAuthentication'" und
|
||||
// würde die ganze App beim Start crashen (appLock wird im RootLayout importiert).
|
||||
// Daher: defensiv laden. Fehlt das Modul → App-Sperre einfach „nicht verfügbar",
|
||||
// der Rest der App läuft normal weiter. In jedem echten Build (EAS / frischer
|
||||
// `expo prebuild`) ist das Modul drin und alles funktioniert.
|
||||
type LocalAuthModule = typeof import('expo-local-authentication');
|
||||
let LocalAuthentication: LocalAuthModule | null = null;
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
|
||||
LocalAuthentication = require('expo-local-authentication') as LocalAuthModule;
|
||||
} catch {
|
||||
LocalAuthentication = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* App-Sperre (Face ID / Touch ID).
|
||||
@ -47,6 +62,11 @@ export const useAppLockStore = create<AppLockState>((set, get) => ({
|
||||
ready: false,
|
||||
|
||||
init: async () => {
|
||||
if (!LocalAuthentication) {
|
||||
// Native-Modul fehlt (alter Dev-Client) → Sperre nicht verfügbar, App läuft weiter.
|
||||
set({ enabled: false, available: false, locked: false, ready: true });
|
||||
return;
|
||||
}
|
||||
const [storedRaw, hasHardware, isEnrolled] = await Promise.all([
|
||||
AsyncStorage.getItem(STORAGE_KEY),
|
||||
LocalAuthentication.hasHardwareAsync(),
|
||||
@ -76,6 +96,7 @@ export const useAppLockStore = create<AppLockState>((set, get) => ({
|
||||
},
|
||||
|
||||
authenticate: async (promptMessage) => {
|
||||
if (!LocalAuthentication) return false;
|
||||
const result = await LocalAuthentication.authenticateAsync({
|
||||
promptMessage: promptMessage ?? DEFAULT_PROMPT,
|
||||
// Geräte-Passcode als Fallback erlauben (Face ID schlägt 3x fehl → Passcode).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user