Respectlytics Respect lytics
Menu
Flutter Password reset Privacy-first

How to track password reset events in Flutter without personal data

Password reset is a small but high-signal funnel — tracking it surfaces UX bugs, rate-limit issues, and email-deliverability problems. Most analytics SDKs default to tagging the request with the user's email or the reset token, both of which are credentials. Respectlytics helps developers avoid collecting personal data in the first place: in Flutter, each step of the reset flow is its own named event, with no payload. Below: instrumentation points, the request → email → reset funnel, and why the reset token never goes near analytics.

Fire one event per step: password_reset_requested (after the user submits their email and the backend accepts it), password_reset_completed (after the new password is set successfully). Don't pass email, token, or user ID — your auth backend has all of them with the right access controls.

Install the Flutter SDK

yaml Respectlytics
# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  respectlytics_flutter: ^3.0.0

Pure Dart — no platform channels for analytics. Same code on every platform Flutter compiles to (iOS, Android, web, macOS, Windows, Linux). On web, events are sent via the REST API; mobile platforms use the same path.

Initialize Respectlytics in Flutter

dart Respectlytics
import 'package:flutter/material.dart';
import 'package:respectlytics_flutter/respectlytics_flutter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Respectlytics.configure(appKey: '<YOUR_APP_KEY>');
  runApp(const MyApp());
}

Initialize in main() after WidgetsFlutterBinding.ensureInitialized() and before runApp(). The future completes immediately on configuration; events queued before completion are flushed once the network is available.

Track the event in Flutter

dart Respectlytics
import 'package:respectlytics_flutter/respectlytics_flutter.dart';

Future<void> requestPasswordReset(String email) async {
  final response = await api.requestPasswordReset(email);
  Respectlytics.track(
    response.ok ? 'password_reset_requested' : 'password_reset_request_failed',
  );
}

Future<void> completePasswordReset(String token, String newPassword) async {
  final response = await api.completePasswordReset(token, newPassword);
  if (response.ok) {
    Respectlytics.track('password_reset_completed');
  }
}

If you handle the reset link as a deep link (e.g. via uni_links), fire password_reset_link_opened from the deep-link handler too — it's a cross-session funnel.

Privacy & implementation notes

The reset token in the email link is a one-time credential that grants account access. Treat it like any other secret: it never leaves your auth backend, never appears in analytics events, never gets logged. Respectlytics's API rejects extra fields, so even an accidental include fails fast.

Password reset spans two sessions by design — the request session and the completion session. Single-session funnel queries will miss most completions. Use the rate of password_reset_completed events relative to password_reset_requested over a 24-hour window; the math is country- and platform-bucketed.

The Flutter SDK is pure Dart. No MethodChannel, no platform-specific iOS or Android plugin code. The same code runs on every platform Flutter supports — including web and desktop targets. This eliminates one common audit surface ("what's the Android implementation doing?").

Always initialize after WidgetsFlutterBinding.ensureInitialized() and before runApp(). If you skip the binding step, the configure call will throw on platforms that need a binding for asynchronous I/O. The SDK documentation example uses this pattern by default.

How this compares to other analytics SDKs

Password reset eventFirebase AnalyticsMixpanelRespectlytics
Email or username as event propertyCommonCommonRejected by API
Reset token storedPossiblePossibleForbidden (credential)
Per-user reset frequencyYesYesOut of scope
Request → completion funnelPer-userPer-userSession-scoped
Rate-limit + abuse detectionPer-user heuristicPer-user heuristicCountry + session aggregate

Frequently asked questions

How do we measure password-reset completion rate without per-user join?

Per-session. A session that emits both password_reset_requested and password_reset_completed is a completing session. The bigger source of drop-off — request → email-clicked — happens between two distinct sessions (the user closes the app, opens the email, taps the link). For that, fire a separate password_reset_link_opened when the deep link lands; the rate from request to link-open is your email-deliverability signal.

What about abuse detection (someone spamming reset requests)?

That's a security concern, not a product analytics concern — handle it in your auth backend with proper rate-limiting and IP-based heuristics. Respectlytics's product-analytics events are not the right surface for abuse-detection signals; abuse logs may legitimately include IPs while product analytics never persists them.

Should we differentiate reset reasons (forgot password vs forced rotation)?

If you have multiple reset flows, distinct event names: password_reset_requested_user_initiated, password_reset_requested_forced_rotation. Most apps have one flow.

What about the actual password change while logged in?

Different event entirely — password_changed. It's a settings-screen action, not a recovery flow. Don't conflate them; their funnels and rates are unrelated.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.