insightreader_sdk 1.0.0 copy "insightreader_sdk: ^1.0.0" to clipboard
insightreader_sdk: ^1.0.0 copied to clipboard

Personalisation for Flutter news apps — reading tracking, time-of-day category insights, streaks, curated notifications, personalised feeds and Gemini AI summaries.

Changelog #

1.0.0 - 2026-08-21 #

First public release on pub.flutter-io.cn. Feature parity with the native iOS InsightreaderSDK, adapted where the platforms genuinely differ.

Security and distribution #

  • Removed the bundle-identifier allowlist. initialize() no longer performs a runtime licence check and its only failure mode is now storageFailure. The allowlist named real customer applications in source, which a published package would have disclosed; it was also bypassable with a two-line dependency override, so it protected nothing. Distribution control is now contractual — see LICENSE. InsightreaderErrorCode.unauthorizedClient and isUnauthorizedClient are gone with it.
  • The AI cache is no longer client-writable. Document ids derive from public article ids, so any client permitted to create summary_<articleId> could seed an entry that every later reader received as a cache hit — and Firestore rules can validate a document's shape but never its contents. Writes now go to AiCacheConfiguration.writeEndpoint, a trusted server-side writer that derives the id itself. Leaving it null means this install never writes.
  • Cache reads are validated. An entry whose kind or articleId disagrees with the document, or which has no generatedAt, is discarded. Entries older than the new maxEntryAge (30 days) are treated as a miss, so any entry written before the lockdown expires on its own.
  • Fixed: disabling the cache also disabled the remote kill switch. The two are now separate settings — remoteKillSwitchEnabled defaults to true and is honoured even when enabled is false. AiCacheConfiguration.disabled opts out of both, which is the only case that needs no Firebase.
  • Deprecated maxDocuments. Client-side eviction required list and delete permission, which the hardened rules withhold. Trim the collection server-side instead.
  • Documented Firestore rules tightened to allow get with list and write denied, plus App Check enforcement.

Analytics — aligned with the shared cross-platform event sheet #

Event names are final as of this release. One dashboard covers iOS, Android and Flutter.

  • All 40 event names now carry the sheet's _gni suffix, and the irsdk_ prefix is gone: irsdk_article_readarticle_read_gni, feed_shownfeed_shown_gni, and so on. All 18 events the sheet lists and this SDK emits now match the sheet exactly.
  • Removed notification_enabled / notification_disabled. Replaced by the sheet's single briefings_enabled_toggled_gni carrying enabled: 1|0 — the old pair double-counted one reader action.
  • Changed briefing_scheduled_gni from one aggregate event per refresh, carrying only the earliest fire time, to one event per slot armed, carrying slot and that slot's trigger_epoch_millis. Expect up to 4× the volume.
  • Changed briefing_permission_blocked_gni to carry slot, emitted once per enabled slot. Permission is still checked once per refresh; every enabled slot really is blocked.
  • Changed ai_summary_failed_gni.error_reason from the raw exception message to the sheet's enum (gemini). The message moved to error_detail, so error_reason is now groupable instead of unbounded.
  • Added ai_summary_cache_hit_gni and ai_summary_cache_miss_gni.
  • Added briefing_tapped_gni (slot, source, category_id).
  • Added insights_shown_gni for the inline streak badge.

sdk_version is still attached to every event as an additive param, and the ai_summary_generated_gni / ai_summary_failed_gni extras (duration_ms, ai_engine, and the rest) are retained alongside the sheet's required keys.

Added #

  • InsightreaderStreakPill — a floating, tappable streak pill, the interactive counterpart to the feed header's inline badge. Emits insights_floating_shown_gni and insights_floating_tapped_gni, completing the sheet's Insights tab.
  • test/analytics_events_test.dart — 18 tests pinning event names, sheet parameter sets, the Firebase name/value constraints, and the emission gate.

Known gaps against the sheet #

41 of the sheet's 59 events remain unemitted. briefing_shown_gni is not implementable (flutter_local_notifications exposes no delivery callback); the rest belong to features this SDK does not have — Widget, In-App Update, Google Sign-in, and the separate streak-reminder and streak-lost notifications. See README section 16 for the full matrix.

Personalisation #

  • Article read tracking with per-category and per-time-of-day aggregation.
  • Most-read category, top categories, and both queries scoped to a time segment.
  • Blended recommendations: 70% time-of-day affinity, 30% overall popularity.
  • Engagement scoring and a reading-rhythm breakdown.
  • Reading streaks with milestones at 3, 7, 14, 30, 60, 100 and 365 days, plus daily reading goals.

Notifications #

  • Four daily briefings, each built around the reader's top category for that segment.
  • Streak-break reminder, independently switchable from the briefings.
  • Per-segment and per-field copy overrides.
  • Persisted reader preferences that survive re-initialization.
  • Typed notification payloads and a tap stream; the SDK never navigates itself.

AI #

  • Gemini-backed summaries, key takeaways and 5W1H extraction, behind a swappable Summarizer interface.
  • Prompts and structured-output schemas ported from the iOS Foundation Models @Generable definitions, so output semantics match.
  • Batch summarisation up to 10 stories, with per-item failure isolation and bounded concurrency.
  • Optional Firestore response cache with FIFO eviction and a remote kill switch.
  • Request coalescing, so concurrent callers for one article share a single call.

Feeds #

  • InsightreaderArticleFeed in four layouts, ranked against the reader's interests.
  • PaginatedArticleFeed with cross-page deduplication and per-page re-ranking.
  • DynamicJsonParser, which finds the articles array at any nesting depth.
  • ArticleMappingConfig covering the string, object and array shapes publisher APIs use for categories and images.
  • Full theming through FeedStyle, FeedTheme and AdaptiveColor.

Other #

  • InsightreaderSettingsScreen, a drop-in reader-preferences screen.
  • Analytics forwarding with event names shared across iOS, Android and Flutter.
  • In-app review and store-page helpers.
  • Typed InsightreaderException with stable error codes throughout.

Deliberate differences from iOS #

  1. maxStoredEvents and analyticsWindowDays are honoured. iOS accepts both but applies neither. Pass analyticsWindowDays: 0 for identical ranking.
  2. Batch concurrency is bounded by maxConcurrentRequests, because Gemini is a metered network API rather than a free on-device model.
  3. AI responses are cached, which iOS has no need for.
  4. HTML block tags are matched case-insensitively, and hexadecimal numeric entities are decoded.
0
likes
140
points
108
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Personalisation for Flutter news apps — reading tracking, time-of-day category insights, streaks, curated notifications, personalised feeds and Gemini AI summaries.

Homepage

Topics

#news #personalization #recommendations #notifications #ai

License

unknown (license)

Dependencies

cached_network_image, cloud_firestore, firebase_core, flutter, flutter_local_notifications, flutter_timezone, http, in_app_review, meta, path, permission_handler, shared_preferences, sqflite, timezone, url_launcher

More

Packages that depend on insightreader_sdk