Skip to content
Back to archipelago.banuacoder.com

Feature SDKs (Pro)

feedback_sdk Pro ​

Tier
Proversion 2.0.4
Command
archipelago generate feedback_sdk
Generates
  • features/feedback/feedback_api
  • features/feedback/feedback_impl
Generates first
storage_sdk, package_info_providerwhen needed and missing, so there is nothing to install first

In-app feedback SDK with offline queue, metadata enrichment, and optional feature voting. Configurable endpoint, app version/device info attachment, and queue limit.

Variables ​

VariableTypeDefaultDescription
includeFeatureVotingbooleantrueEnable feature-request listing and voting (GET/POST /feature-requests) — templated into FeedbackConfig.featureVotingEnabled
defaultEndpointstring""Default endpoint URL pre-filled in FeedbackConfig.endpoint (can be changed later)

Install ​

Interactive ​

bash
archipelago generate feedback_sdk

Non-interactive (CI) ​

bash
archipelago generate feedback_sdk --config my_config.json

Prerequisites ​

  • An existing Archipelago workspace (archipelago.yaml at the project root, written by flutter_modular_monorepo); pre_gen exits otherwise.
  • storage_sdk — self-generated automatically (SubBrickGenerator) if not already installed. feedback_impl's offline queue is AppStorage-backed via storage_sdk_api's StorageProvider, requesting its own 'feedback' namespace — this avoids the duplicate-SharedPreferences-registration crash that hit two other features before 1.2.0.
  • package_info_provider — also self-generated automatically (SubBrickGenerator; since 1.4.2) if not already installed. feedback_impl resolves PackageInfo from that brick's single global registration instead of registering its own (fixed in 1.3.0, for the same class of GetIt duplicate-registration crash).

Generated Structure ​

text
features/
└── feedback/
    ├── feedback_api/
    │   └── lib/src/
    │       └── models/
    └── feedback_impl/
        └── lib/src/
            ├── data/
            └── di/

Public API ​

dart
final feedbackSDK = getIt<FeedbackSDK>();

final result = await feedbackSDK.submit(
  FeedbackSubmission(text: 'The checkout button is hard to find', category: FeedbackCategory.bug),
);
// result: FeedbackSubmitResultSubmitted | FeedbackSubmitResultQueued (offline/5xx) | FeedbackSubmitResultFailed (4xx)

await feedbackSDK.getQueuedCount();   // items currently queued offline
await feedbackSDK.flushQueue();       // POST queued items now, returns count flushed
await feedbackSDK.clearQueue();       // drop the queue without sending

final requests = await feedbackSDK.getFeatureRequests(page: 1, pageSize: 20);
await feedbackSDK.voteOnFeatureRequest(requests.first.id); // locally deduplicated
await feedbackSDK.submitFeatureRequest(title: 'Dark mode', description: '...');

feedbackSDK.config; // active FeedbackConfig

Endpoint Configuration ​

The generated FeedbackRegisterModule (feedback_impl/lib/src/di/register_module.dart) provides the default FeedbackConfig, templated from defaultEndpoint and includeFeatureVoting:

dart
featureVotingEnabled: true, // or false, from includeFeatureVoting

To customise it, override FeedbackConfig with your own @module:

dart
@module
abstract class AppFeedbackModule {
  @lazySingleton
  FeedbackConfig get feedbackConfig => const FeedbackConfig(
    endpoint: 'https://api.yourapp.com/feedback',
    attachAppVersion: true,
    attachDeviceInfo: true,
    featureVotingEnabled: true,
  );
}

Register this module before FeedbackImplPackageModule.

Offline Queue ​

Submissions and votes are held in AppStorage (via storage_sdk_api, under a 'feedback' namespace — not raw SharedPreferences directly) when the device is offline or the server returns a 5xx. Each queued item carries a kind discriminator (feedback or feature_request) so flushQueue() dispatches it to the right endpoint. Wire connectivity_sdk to flush the queue automatically:

dart
connectivitySDK.stateStream.listen((state) {
  feedbackSDK.recordConnectivity(online: state.isOnline);
});

The queue drains automatically when connectivity is restored.

Shake-to-Feedback (Optional) ​

Install shake and call submit() from a ShakeDetector callback:

dart
ShakeDetector.autoStart(
  onPhoneShake: () async {
    await feedbackSDK.submit(
      FeedbackSubmission(
        text: await _promptUserForText(),
        category: FeedbackCategory.general,
      ),
    );
  },
);

Feature Voting ​

When FeedbackConfig.featureVotingEnabled is true, users can browse, vote on, and submit feature requests:

dart
final requests = await feedbackSDK.getFeatureRequests();
final result = await feedbackSDK.voteOnFeatureRequest(requests.first.id);
await feedbackSDK.submitFeatureRequest(title: 'Dark mode', description: '...');

Votes are locally deduplicated — a second call for the same requestId returns FeatureRequestVoteResultAlreadyVoted without hitting the network. When voting is disabled, getFeatureRequests returns an empty list and voteOnFeatureRequest/submitFeatureRequest return a failure result with reason featureVotingDisabled.

DI & Wiring ​

FeedbackImplPackageModule is declared under the archipelago: di_modules: manifest key with depends_on: [storage_sdk_shared_preferences, package_info_provider] — monorepo_toolkit generate host-registry uses this to order the generated injector's module registrations correctly.

The module's own Dio is registered as @Named('feedback'), so it does not collide with the app-wide Dio from network_sdk_dio. To reuse it, resolve getIt<Dio>(instanceName: 'feedback').

Dependencies ​

feedback_impl: dio ^5.11.0, device_info_plus ^13.2.0, package_info_plus ^10.2.1 (the PackageInfo instance itself comes from package_info_provider's global registration, not a second one here), plus workspace storage_sdk_api.

Platform Setup ​

None beyond what device_info_plus/package_info_plus/storage_sdk already require.

Limitations ​

  • The generated FeedbackSDK implementation is a lazy @LazySingleton(as: FeedbackSDK) (since 2.0.0); nothing runs at boot, and the app flushes the queue through flushQueue() or recordConnectivity().
  • Shake-to-feedback requires manually adding the third-party shake package; it is not a brick dependency.

Changelog ​

Run archipelago brick info feedback_sdk to see the latest published version. Enterprise customers can read the full CHANGELOG.md in the brick source repository.