liquid_firebase 0.2.0 copy "liquid_firebase: ^0.2.0" to clipboard
liquid_firebase: ^0.2.0 copied to clipboard

Firebase Analytics (Google Analytics for Firebase / GA4) destination for liquid_analytics.

liquid_firebase #

Firebase Analytics (Google Analytics for Firebase / GA4) destination for liquid_analytics.

Install #

dependencies:
  liquid_analytics: ^0.2.0
  liquid_firebase: ^0.2.0
  firebase_core: ^3.0.0

Use #

Initialize Firebase, then add FirebaseSink to your Liquid client:

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

final liquid = Liquid(
  sinks: [FirebaseSink()],
  consent: ConsentPolicy(
    requireOptIn: true,
    map: {ConsentCategory.analytics: ['firebase']},
  ),
);
await liquid.init();

liquid.track('checkout_started', {'cart_value': 42.0, 'is_gift': true});
liquid.consent.grant(ConsentCategory.analytics);

The string API above is the quick path. A typed event keeps the name and property keys in one place — and for Firebase specifically, it pins the sanitizer-legal snake_case naming at the definition site instead of relying on every call site to get it right:

class CheckoutStarted extends LiquidEvent {
  const CheckoutStarted({required this.cartValue, this.isGift = false});
  final double cartValue;
  final bool isGift;

  @override
  String get name => 'checkout_started'; // already Firebase-legal

  @override
  Map<String, Object?> get properties => {
        'cart_value': cartValue,
        'is_gift': isGift, // encoded as 1/0 by FirebaseEventMapper
      };
}

liquid.log(const CheckoutStarted(cartValue: 42, isGift: true));

No build step is involved — it is a plain class. Override category to route an event to a different consent bucket (e.g. ConsentCategory.marketing). To generate these from a YAML schema instead, see liquid_codegen.

Message mapping #

liquid message Firebase call
track logEvent
screen logScreenView
identify setUserId + setUserProperty per trait
reset resetAnalyticsData

Firebase has no group or alias concept, so those are ignored and the sink does not advertise those capabilities (the client skips it for them).

Automatic sanitization #

Firebase rejects data that liquid's Map<String, Object?> allows: parameter values must be a String or a number, names must be alphanumeric/underscore and start with a letter, and there are length and count limits. FirebaseEventMapper enforces all of this so events are never silently dropped by the native layer:

  • Illegal name characters become underscores; names are truncated to 40 chars (24 for user properties) and forced to start with a letter.
  • Booleans are encoded as 1/0 (configurable), enums by .name, DateTime as ISO-8601. Nested lists/maps are dropped.
  • String values are truncated to 100 chars; parameters are capped at 25.

Tune it by passing your own mapper:

FirebaseSink(mapper: const FirebaseEventMapper(boolsAsInts: false));

Optionally mirror liquid's consent into Firebase Consent Mode so Firebase itself honors the user's choice:

final firebaseSink = FirebaseSink();
final liquid = Liquid(sinks: [firebaseSink]);

liquid.consent.addListener(() {
  firebaseSink.applyConsent(
    analyticsGranted: liquid.consent.statusOf(ConsentCategory.analytics) ==
        ConsentStatus.granted,
    adsGranted: liquid.consent.statusOf(ConsentCategory.marketing) ==
        ConsentStatus.granted,
  );
});

Testing #

The sanitization logic lives in the pure FirebaseEventMapper, which is unit- testable without a configured Firebase app. For end-to-end verification, run your app against a real Firebase project and inspect DebugView.

0
likes
160
points
13
downloads

Documentation

API reference

Publisher

verified publisherketok.id

Weekly Downloads

Firebase Analytics (Google Analytics for Firebase / GA4) destination for liquid_analytics.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#analytics #firebase #flutter

License

MIT (license)

Dependencies

firebase_analytics, flutter, liquid_analytics, meta

More

Packages that depend on liquid_firebase