Flutter SDK reference
Dart lifecycle, reactive feature state, event streams, and typed operation results.
The Flutter SDK provides a Dart client, feature listeners, and activity streams. Configure the SDK before making calls through Nuxie.instance.
Configuration and lifecycle
Nuxie.instance implements NuxieClient. Pass the interface into application services or widgets so tests can supply a fake client.
| Configuration | Default | Description |
|---|---|---|
apiKeys |
Required | NuxieApiKeys(ios: ..., android: ...). |
environment |
NuxieEnvironment.production |
Production or development service. |
logLevel |
NuxieLogLevel.warning |
debug, info, warning, error, or none. |
localeIdentifier |
null |
Follow the device locale, or provide an override. |
billing |
NuxieBilling.native() |
Native billing or an external controller. |
Use the public pk_test_ key for preview content and the pk_live_ key for live content. Keep the default service environment for both. The development environment selects a separate Nuxie service; it does not select test mode for your app.
Equivalent concurrent configure() calls share setup. A different configuration requires await shutdown() first. isConfigured becomes true after setup completes; versions exposes the wrapper, native version, and bridge contract.
Identify a customer
import 'package:nuxie_flutter/nuxie_flutter.dart';
final nuxie = Nuxie.instance;
await nuxie.identify('customer_123', userProperties: {'plan': 'pro'});
getDistinctId() and getAnonymousId() return the current IDs. Call reset() when the customer signs out; the anonymous ID rotates by default.
identify() also accepts userPropertiesSetOnce for values that should be set only when missing. Use getIsIdentified() to distinguish a known customer from an anonymous one. reset(keepAnonymousId: true) explicitly preserves the anonymous ID.
setLocaleIdentifier('fr_FR') changes the locale used at the next profile synchronization. Pass null to restore the device locale.
Trigger an Experience
await nuxie.trigger('upgrade_requested', properties: {'source': 'settings'});
The Future completes after native invocation. Whether an Experience appears depends on its published delivery rules. Call dismiss() to close the current presentation.
Read feature access
nuxie.features is a ValueListenable<NuxieFeatureSnapshot>. NuxieFeatureBuilder rebuilds a widget when its selected feature changes. Read the state as well as the access value: unknown means access is still loading.
To query access directly:
final access = await nuxie.hasFeature('premium-export');
if (access.allowed) {
// Enable premium export.
}
The default policy uses fresh cached access. Pass policy: FeatureCheckPolicy.remote for a server query. requiredBalance and entityId select the amount and entity to check.
For example, render a selected feature with the same client used to configure the SDK:
NuxieFeatureBuilder(
client: Nuxie.instance,
featureId: 'premium-export',
builder: (context, access, state) {
if (state == FeatureState.unknown) {
return const CircularProgressIndicator();
}
return Text(access?.allowed == true ? 'Export available' : 'Upgrade to export');
},
)
Import Flutter’s Material widgets for this example. The builder requires client, featureId, and builder; it manages its feature listener with the widget lifecycle.
Feature state
A snapshot contains state, all, identityGeneration, and revision. state is unknown while loading, reconciling while purchase access is being synchronized, or ready. A ready snapshot may be empty.
Each FeatureAccess has allowed, unlimited, nullable balance, and type. Missing access is distinct from a zero balance. NuxieFeatureBuilder passes (context, access, state) to its builder and does not fetch or consume usage.
Entity queries use grants assigned to that entity and do not replace the global snapshot. A failed query throws; a successful query can return allowed: false.
Consume usage
final receipt = await nuxie.consumeFeature(
'credits',
quantity: 5,
operationId: 'generation_123',
);
if (receipt.accepted) {
// Start the generation once.
}
Keep the operation ID with the action and reuse it for retries. A remaining balance of zero can accompany an accepted final use. A network error does not prove the deduction was cancelled.
Consumption and usage results
FeatureConsumptionResult contains operationId, customerId, featureId, nullable occurredAtMs, accepted, code, quantity, balance, unlimited, active, and idempotentReplay. Match a returned receipt to the customer and saved action before applying its effect.
Quantities must be positive whole units up to 9,007,199,254,740,991. For shared credits, query and consume the credit feature’s key using the action’s credit cost.
Usage reporting
| Method | Behavior |
|---|---|
useFeature(id, amount: 1, entityId:, metadata:) |
Enqueues usage without waiting for server confirmation. |
useFeatureAndWait(id, amount: 1, entityId:, setUsage: false, metadata:) |
Waits for FeatureUsageResult; inspect success. |
FeatureUsageResult includes featureId, amountUsed, optional message, optional usage, and optional authoritativeAccess. Use consumeFeature() when your app needs to retain an explicit operation ID across retries.
With setUsage: true, the amount is a cumulative total: reporting 20 then 25 charges 20 then 5. A lower later total does not restore credits. Use one reporting method per action so it is not charged twice.
Activity and App Actions
final subscription = nuxie.appActions.listen((action) {
// Handle action.name and action.payload.
});
Use appActions to connect an Experience to your Flutter app, such as opening the library after onboarding. activities reports what happened in Nuxie for analytics and UI updates. Both are live broadcast streams. Subscribe before the operation you want to observe and cancel the subscription when finished. They do not replay past events.
An activity contains schemaVersion, id, name, UTC timestamp, receivedAt, and immutable properties. An App Action contains its name, optional payload, and Experience reference. Validate action data before performing app-specific work.
Restore purchases
restorePurchases() returns a RestoreResult: restored, noPurchases, or failed. Purchases use the configured native billing integration or your external NuxiePurchaseController.
External checkout
Set billing: NuxieBilling.external(controller) before configuration. The controller implements Future<PurchaseResult> purchase(NuxieStoreProduct product) and Future<RestoreResult> restorePurchases().
Return PurchaseResult.purchased(), .cancelled(), .pending(), or .failed(message). Restore returns RestoreResult.restored(), .noPurchases(), or .failed(message).
The supplied product includes the selected store identifiers, offer, placement, price fields, and platform-specific billing terms. Preserve these when opening provider checkout. Available fields vary by platform; do not substitute a different offer when a term is absent or unsupported. Return a failure instead.
For native billing where your app finishes transactions, use NuxieBilling.native(handling: PurchaseHandlingMode.observer).
Product fields
NuxieStoreProduct contains:
| Fields | Description |
|---|---|
platform, productId, storeProductId |
Platform and product identity. |
basePlanId, purchaseOptionId, offerId, placementId |
Optional identifiers for the selected placement and store offer. |
displayName, description, displayPrice, productType |
Product display information, when available. |
period, periodCount, billingPlan |
Optional subscription terms. |
eligibilityJws, introductoryTerms |
Optional introductory offer eligibility and terms. |
NuxieIntroductoryTerms contains price, period, periodCount, cycles, paymentMode, and displayDuration. Keep absent values nullable when passing a product to your provider.
Errors and cleanup
Commands throw NuxieException with code, message, and optional details. Invalid Dart arguments throw ArgumentError. Purchase and restore business outcomes use typed results rather than transport exceptions.
Cancel stream subscriptions when the owner is disposed. await nuxie.shutdown() settles outstanding controller requests and resets feature state to unknown. Wait for shutdown before configuring again. A thrown network error does not prove a durable usage command was cancelled; retry the saved command with its original ID.
Event and customer properties must be finite JSON values. Cyclic structures, non-finite numbers, and event names starting with the reserved $ prefix are rejected.
See Features and entitlements for access configuration and the Dart API reference for all options and result fields.