MotorSignal-App/lib/services/cloud/firebase_account_sync_servi...

71 lines
2.4 KiB
Dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import '../../database/database.dart';
import '../auth/auth_service.dart';
import 'cloud_models.dart';
/// Synchronizes account/profile and motorcycle metadata independently of the
/// ride upload pipeline. This keeps identity data small and queryable while
/// leaving high-frequency telemetry in the existing ride/R2 path.
class FirebaseAccountSyncService {
final AppDatabase _db;
final AuthService _auth;
final FirebaseFirestore? _firestore;
FirebaseAccountSyncService({
required this._db,
required this._auth,
FirebaseFirestore? firestore,
}) : _firestore = firestore ?? _resolveFirestore();
static FirebaseFirestore? _resolveFirestore() {
try {
if (Firebase.apps.isNotEmpty) return FirebaseFirestore.instance;
} catch (_) {}
return null;
}
bool get isAvailable => _firestore != null && Firebase.apps.isNotEmpty;
Future<void> syncAccount({DateTime? now}) async {
final user = _auth.currentUser;
if (user == null || user.isAnonymous || !isAvailable) return;
final timestamp = (now ?? DateTime.now()).toUtc();
final profile = CloudUserProfile(
id: user.uid,
displayName: user.displayName,
profilePhotoUrl: user.photoUrl,
createdAt: user.createdAt?.toUtc() ?? timestamp,
updatedAt: timestamp,
);
final userRef = _firestore!.collection('users').doc(user.uid);
await userRef.set(profile.toJson(), SetOptions(merge: true));
final motorcycles = await _db.select(_db.garageMotorcycles).get();
for (final motorcycle in motorcycles) {
final cloud = CloudMotorcycle(
id: motorcycle.id.toString(),
ownerId: user.uid,
year: motorcycle.year,
makeId: motorcycle.makeId,
makeName: motorcycle.makeName,
modelId: motorcycle.modelId,
modelName: motorcycle.modelName,
variantId: motorcycle.variantId,
variantName: motorcycle.variantName,
nickname: motorcycle.nickname,
isDefault: motorcycle.isDefault,
createdAt: motorcycle.dateAdded.toUtc(),
updatedAt: motorcycle.lastUpdated.toUtc(),
specificationJson: motorcycle.specificationJson,
);
await userRef.collection('motorcycles').doc(cloud.id).set(
cloud.toJson(),
SetOptions(merge: true),
);
}
}
}