Fingerprinting
Norrix uses fingerprinting to determine if an OTA update is compatible with a deployed native binary. The fingerprint captures the state of native dependencies to ensure safe updates.
What Gets Fingerprinted
1. Native Plugins
All npm packages with NativeScript native code:
- Detected by checking for
nativescriptkey in package.json - Version numbers are captured from installed packages
2. App_Resources
Contents of your App_Resources folder:
- Recursive hash of all files
- Excludes hidden files (
.DS_Store, etc.) - Excludes the fingerprint file itself
3. Native Sources
Custom native code defined in nativescript.config.ts:
- Files matching
NativeSourcepatterns - Hashed and included in fingerprint
norrix fingerprint
Print the fingerprint for your project.
Synopsis
norrix fingerprint [platform] [options]Arguments
| Argument | Description |
|---|---|
platform | Target platform: ios, android, or visionos |
Options
| Flag | Description |
|---|---|
--app-id <appId> | Optional app ID to include in the fingerprint |
Output
Displays fingerprint details:
- Hash (SHA-256)
- Native plugins with versions
- App_Resources hash
- NativeSource hash (if applicable)
Examples
# Print iOS fingerprint
norrix fingerprint ios
# Print Android fingerprint with app ID
norrix fingerprint android --app-id com.example.myappnorrix fingerprint compare
Compare fingerprints between a stored build and another build or local project.
Synopsis
norrix fingerprint compare --from <buildId> [--to <buildIdOrLocal>]Options
| Flag | Description |
|---|---|
--from <buildId> | Source build ID to compare from (required) |
--to <buildIdOrLocal> | Target build ID or local (default: local) |
Behavior
When comparing:
- Fetches the fingerprint from the source build
- Computes or fetches the target fingerprint
- Compares all fingerprint components
- Reports compatibility and differences
Examples
# Compare build to local project
norrix fingerprint compare --from build-123
# Compare two builds
norrix fingerprint compare --from build-123 --to build-456Output
The comparison shows:
- Compatible: ✅ OTA updates are safe
- Incompatible: ❌ A new store build is required
If incompatible, the output details what changed:
- Plugin version changes
- App_Resources changes
- NativeSource changes
Fingerprint File
At build time, Norrix writes a fingerprint file to your app’s assets:
assets/norrix.fingerprint.jsonExample content:
{
"createdAt": "2024-01-01T00:00:00.000Z",
"platform": "ios",
"hash": "abc123def456...",
"nativePlugins": {
"@nativescript/core": "8.6.0",
"nativescript-camera": "4.5.0",
"@nativescript/imagepicker": "1.0.0"
},
"appResourcesHash": "def456...",
"nativeSourcesHash": "ghi789..."
}This file is bundled into the app binary and read at runtime by the Client SDK.
How Fingerprinting Works
At Build Time
- Norrix computes the fingerprint from your project
- The hash is stored in the build record
- The fingerprint file is written to
assets/ - The file is included in the native binary
At Update Time
- Norrix computes the fingerprint from your project
- The hash is stored with the update record
- When a device checks for updates, fingerprints are compared
At Runtime
- The Client SDK reads the bundled fingerprint file
- On update check, the SDK sends its fingerprint to the server
- The server compares fingerprints
- If compatible: returns OTA download URL
- If incompatible: returns
requiresStoreUpdate: true
Fingerprint Caching
The SDK caches the native binary’s fingerprint in ApplicationSettings:
- Key:
Norrix_Binary_Fingerprint - Persists across OTA updates
- Ensures the original native fingerprint is always used
This prevents the fingerprint from changing when running from an OTA bundle stored in a different location.
Best Practices
- Check before publishing: Run
norrix fingerprint comparebefore publishing OTA updates - Version native plugins carefully: Plugin updates often require new store builds
- Monitor App_Resources: Changes to icons, launch screens, etc. require store builds
- Use NativeSource patterns: Declare all custom native code in
nativescript.config.ts