Amplitude¶
Herald's Amplitude module sends events to Amplitude with typed properties. Amplitude usually gets every event:
- screen views use Amplitude's own
[Amplitude] Screen Viewed; - purchases go through Amplitude's revenue API.
| SDK | Package |
|---|---|
| Android | io.github.mkhytarmkhoian:herald-amplitude |
| Flutter | herald_amplitude, over amplitude_flutter |
| iOS | herald-ios-amplitude, module HeraldAmplitude, over Amplitude-Swift |
| React Native | @herald-analytics/amplitude, over @amplitude/analytics-react-native |
Setup¶
You build the Amplitude instance: API key, server zone, autocapture and the rest of its
Configuration. On React Native, you call amplitude.init(...) with those options and give Herald
the amplitude module itself. Herald never changes them.
// optOut = true: silent until consent. Autocapture stays at its default (sessions only), so
// screen views come from Herald's factory and are not counted twice.
val amplitude = Amplitude(Configuration(apiKey, context, optOut = true))
val tracker = AmplitudeAnalyticsTrackerService(
CompositeAmplitudeEventTrackerFactory(
featureFactories + // your revenue trackers, among others
ScreenViewAmplitudeEventTrackerFactory(amplitude) + // [Amplitude] Screen Viewed
GenericAmplitudeEventTrackerFactory(amplitude), // everything else
),
CompositeAmplitudePropertySetterFactory(
GenericAmplitudePropertySetterFactory(amplitude), // user properties
),
)
val service = AmplitudeAnalyticsService(amplitude)
val provider = Herald.Provider(
name = "amplitude",
events = tracker,
properties = tracker,
identity = service,
lifecycle = service,
consent = service,
)
// Herald sends screen views, so leave .screenViews out of autocapture, as by default.
let amplitude = Amplitude(
configuration: Configuration(apiKey: apiKey, optOut: true)) // silent until consent
let tracker = AmplitudeAnalyticsTrackerService(
eventTrackerFactory: CompositeAmplitudeEventTrackerFactory([
ScreenViewAmplitudeEventTrackerFactory(amplitude: amplitude),
GenericAmplitudeEventTrackerFactory(amplitude: amplitude),
]),
propertySetterFactory: GenericAmplitudePropertySetterFactory(amplitude: amplitude)
)
let service = AmplitudeAnalyticsService(amplitude: amplitude)
let provider = HeraldProvider(
name: "amplitude",
events: tracker,
properties: tracker,
identity: service,
lifecycle: service,
consent: service
)
final amplitude = Amplitude(
Configuration(
apiKey: apiKey,
optOut: true, // silent until consent
autocapture: const AutocaptureOptions(screenViews: false), // Herald sends screen views
),
);
final tracker = AmplitudeAnalyticsTrackerService(
eventTrackerFactory: CompositeAmplitudeEventTrackerFactory([
ScreenViewAmplitudeEventTrackerFactory(amplitude),
GenericAmplitudeEventTrackerFactory(amplitude),
]),
propertySetterFactory: CompositeAmplitudePropertySetterFactory([
GenericAmplitudePropertySetterFactory(amplitude),
]),
);
final service = AmplitudeAnalyticsService(amplitude);
final provider = HeraldProvider(
name: 'amplitude',
events: tracker,
properties: tracker,
identity: service,
lifecycle: service,
consent: service,
);
amplitude.init(apiKey, undefined, { optOut: true }); // silent until consent
const tracker = new AmplitudeAnalyticsTrackerService({
eventTrackerFactory: new CompositeAmplitudeEventTrackerFactory([
new ScreenViewAmplitudeEventTrackerFactory(amplitude),
new GenericAmplitudeEventTrackerFactory(amplitude),
]),
propertySetterFactory: new CompositeAmplitudePropertySetterFactory([
new GenericAmplitudePropertySetterFactory(amplitude),
]),
});
const service = new AmplitudeAnalyticsService(amplitude);
const provider = new HeraldProvider({
name: 'amplitude',
events: tracker,
properties: tracker,
identity: service,
lifecycle: service,
consent: service,
});
What reaches Amplitude¶
| Herald | Amplitude |
|---|---|
| an event | track(name, properties), with each value as its own JSON type |
a ScreenViewEvent |
[Amplitude] Screen Viewed with its name as [Amplitude] Screen Name; a screen view with its own [Amplitude] Screen Name parameter is refused and reported |
an AmplitudeRevenueEvent |
revenue(Revenue), deduplicated by insertId when set |
a property, including a UserProperty |
identify(Identify().set(name, value)): a user property |
identify / reset |
setUserId(userId) / reset(), which also rotates the device id |
start |
waits for the SDK to finish setting up, so a failed setup is reported; nothing on iOS and React Native |
flush |
flush() |
setEnabled |
optOut = !enabled; setOptOut(!enabled) on React Native |
Factories and revenue types¶
| Factory | Handles |
|---|---|
ScreenViewAmplitudeEventTrackerFactory |
every ScreenViewEvent |
GenericAmplitudeEventTrackerFactory |
everything else; usually last in the chain |
GenericAmplitudePropertySetterFactory |
every property |
RequireMappedAmplitudeEventTrackerFactory, RequireMappedAmplitudePropertySetterFactory |
nothing: throws for anything that reaches it |
For a purchase, your factory maps your event to AmplitudeRevenueEvent and hands it to
RevenueEventTracker (RevenueAmplitudeEventTracker on Flutter, iOS and React Native); put that
factory before the
generic one. The type uses Amplitude's own
fields:
price,quantity,productId,revenueType,currency;revenue, for a total that isn'tprice × quantity;receiptandreceiptSig;insertId, passed on the call's options, since Amplitude'sRevenuehas no field for it.
See Revenue.
Consent¶
A fresh install collects unless the Configuration sets optOut = true (optOut: true on
Flutter, iOS and React Native). Amplitude doesn't
persist the opt-out, so re-apply the stored decision after start-up. Revoking stops new events;
events recorded before the revoke, while consent was given, may still upload.
Watch out for¶
- Autocapture and screen views. Keep Amplitude's screen-view autocapture off while using
ScreenViewAmplitudeEventTrackerFactory, or every screen is counted twice. The default autocapture setting is sessions only. reset()rotates the device id, so a signed-out user starts a new anonymous device in Amplitude.HeraldCore.Identityon iOS. Amplitude's iOS SDK has anIdentitytype too, so in a file that imports both modules, writeHeraldCore.Identity(userId: id).- A factory of your own that stores your
Amplitudeneeds@preconcurrency import AmplitudeSwifton iOS, because Amplitude isn't markedSendable. Xcode offers the fix.