frosty/lib/apis/firebase_performance_interceptor.dart
Tommy Chow 6ede000c66 improve Firebase integration across Crashlytics, Analytics, and Performance
- Fix cold-start privacy bug: apply persisted collection preference on launch
- Disable Firebase collection in debug builds to avoid polluting prod data
- Add Crashlytics custom keys (is_logged_in, channel), user identifier, and
  WebSocket reconnection breadcrumbs for actionable crash reports
- Record non-fatal errors for server failures, WebSocket errors, and global
  asset fetch failures (skip timeouts/network errors to avoid noise)
- Update is_logged_in key and user identifier on login/logout transitions
- Log auth reconnection exhaustion before forced logout
- Add FirebaseAnalyticsObserver with named routes for automatic screen tracking
- Add static routeName constants to avoid duplicated string literals
- Add Firebase Performance Dio interceptor for automatic HTTP request tracing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:18:21 -08:00

46 lines
1.5 KiB
Dart

import 'package:dio/dio.dart';
import 'package:firebase_performance/firebase_performance.dart';
/// Dio interceptor that traces HTTP requests as Firebase Performance metrics.
class FirebasePerformanceInterceptor extends Interceptor {
static const _metricKey = 'firebase_performance_metric';
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
final metric = FirebasePerformance.instance.newHttpMetric(
options.uri.toString(),
_getHttpMethod(options.method),
);
metric.start();
options.extra[_metricKey] = metric;
handler.next(options);
}
@override
void onResponse(Response response, ResponseInterceptorHandler handler) {
_stopMetric(response.requestOptions, response.statusCode);
handler.next(response);
}
@override
void onError(DioException err, ErrorInterceptorHandler handler) {
_stopMetric(err.requestOptions, err.response?.statusCode);
handler.next(err);
}
void _stopMetric(RequestOptions options, int? statusCode) {
final metric = options.extra.remove(_metricKey) as HttpMetric?;
if (metric == null) return;
if (statusCode != null) metric.httpResponseCode = statusCode;
metric.stop();
}
static HttpMethod _getHttpMethod(String method) => switch (method.toUpperCase()) {
'GET' => HttpMethod.Get,
'POST' => HttpMethod.Post,
'PUT' => HttpMethod.Put,
'DELETE' => HttpMethod.Delete,
'PATCH' => HttpMethod.Patch,
_ => HttpMethod.Get,
};
}