getMyDevices method
Gets all devices registered for the current user.
Returns a list of all device documents under users/{uid}/devices/,
ordered by lastActiveAt descending (most recent first).
Requirements
- User must be authenticated
- Implemented via backend callable (no direct client Firestore reads)
Use Cases
- Displaying a "My Devices" settings screen
- Admin/debugging tools
- Showing which device will receive notifications
Returns
Right(List<DeviceInfo>)with all user's devicesLeft(RepositoryFailure)on failure or if not authenticated
Example
final result = await deviceService.getMyDevices();
result.fold(
(failure) => showError('Could not load devices'),
(devices) {
for (final device in devices) {
print('${device.platform}: ${device.timezone}');
}
},
);
Implementation
@override
Future<Either<RepositoryFailure, List<DeviceInfo>>> getMyDevices() async {
logd('DeviceService: getMyDevices called');
try {
final deviceId = await getDeviceId();
final result = await _deviceCallable.call({
'action': 'getMyDevices',
'deviceId': deviceId, // Required for callable validation
});
final data = Map<String, dynamic>.from(result.data as Map);
if (data['success'] != true) {
logw('DeviceService: getMyDevices response indicated failure');
return const Left(RepositoryFailure.unexpected);
}
final devicesData = data['devices'] as List<dynamic>? ?? [];
final devices = devicesData.map((deviceData) {
final deviceMap = Map<String, dynamic>.from(deviceData as Map);
// The server returns 'id' as the document ID, map it to deviceId
if (deviceMap.containsKey('id') && !deviceMap.containsKey('deviceId')) {
deviceMap['deviceId'] = deviceMap['id'];
}
return DeviceInfo.fromJson(deviceMap);
}).toList();
logd('DeviceService: Retrieved ${devices.length} devices');
return Right(devices);
} on FirebaseFunctionsException catch (e) {
loge(e, 'DeviceService: Firebase Functions error during getMyDevices');
return _mapFirebaseFunctionsException(e);
} catch (e) {
loge(e, 'DeviceService: Unexpected error during getMyDevices');
return const Left(RepositoryFailure.unexpected);
}
}