tryInitialiseStream method
Initializes the authentication state stream and data synchronization.
Sets up listeners for user authentication changes and manages the data stream.
Implementation
Future<void> tryInitialiseStream() async {
_log.info('Initialising TurboAuthSyncService stream..');
try {
_userSubscription ??= FirebaseAuth.instance.userChanges().listen(
(user) async {
final userId = user?.uid;
if (userId != null) {
cachedUserId = userId;
await onAuth?.call(user!);
// Ensure auth token is ready and cached before starting Firestore stream
// This ensures Firestore security rules have access to request.auth
try {
await _ensureAuthTokenReady(user!);
} catch (error, stackTrace) {
_log.error(
'Failed to ensure auth token ready, proceeding anyway',
error: error,
stackTrace: stackTrace,
);
// Continue - let the stream attempt and retry mechanism handle failures
}
// Cancel any existing subscription before creating a new one
// This ensures we start fresh with the token-ready user
await _subscription?.cancel();
_subscription = null;
_subscription = (await stream(user!)).listen(
(value) async {
await onData(value, user);
},
onError: (Object error, StackTrace stackTrace) {
_log.error(
'Stream error occurred inside of stream!',
error: error,
stackTrace: stackTrace,
);
// Convert error to TurboFirestoreException if needed
final exception = error is TFirestoreException
? error
: TFirestoreException.fromFirestoreException(
error,
stackTrace,
operationType: TOperationType.stream,
);
// Call onError handler
onError(exception);
_tryRetry();
},
onDone: () => onDone(_nrOfRetry, _maxNrOfRetry),
);
} else {
cachedUserId = null;
_clearTokenCache();
await _subscription?.cancel();
_subscription = null;
await onData(null, null);
}
},
);
} catch (error, stack) {
_log.error(
'Stream error occurred while setting up stream!',
error: error,
stackTrace: stack,
);
// Convert error to TurboFirestoreException if needed
final exception = error is TFirestoreException
? error
: TFirestoreException.fromFirestoreException(
error,
stack,
operationType: TOperationType.stream,
);
// Call onError handler
onError(exception);
_tryRetry();
}
}