gms_trusted_time
A Flutter plugin that provides tamper-resistant, accurate UTC timestamps via the official Google Play Services TrustedTime API.
Unlike DateTime.now(), which reads the device's user-modifiable system clock, this plugin sources time directly from Google's secure time-keeping infrastructure — making it reliable even if the user has changed their device time.
Why use this?
| Scenario | DateTime.now() |
gms_trusted_time |
|---|---|---|
| User changes device clock | ❌ Affected | ✅ Immune |
| Device offline after first sync | ✅ Works | ✅ Works |
| Hardware clock drift | ❌ Undetected | ✅ GMS compensates |
| Requires internet on every call | ✅ No | ✅ No |
| Works without Google Play Services | ✅ Yes | ❌ Returns null |
Platform Support
| Android | iOS | Web | Desktop |
|---|---|---|---|
| ✅ | ❌ | ❌ | ❌ |
Note: This plugin is Android-only. It requires Google Play Services (available on all standard Android 5.0+ devices).
Installation
Add to your pubspec.yaml:
dependencies:
gms_trusted_time: ^1.0.0
No additional permissions or manifest entries are required. The TrustedTime API requires no special permissions.
Usage
import 'package:gms_trusted_time/gms_trusted_time.dart';
final plugin = GmsTrustedTime();
Future<void> checkTime() async {
final trustedMillis = await plugin.getTrustedTimeMillis();
if (trustedMillis != null) {
final trustedTime = DateTime.fromMillisecondsSinceEpoch(
trustedMillis,
isUtc: true,
);
print('Trusted UTC time: $trustedTime');
// Compare with system clock
final systemMillis = DateTime.now().millisecondsSinceEpoch;
final driftMs = trustedMillis - systemMillis;
print('Clock drift: ${driftMs}ms');
} else {
// Fallback: device hasn't connected to internet since last boot,
// or Google Play Services is unavailable.
print('Trusted time unavailable. Use system clock as fallback.');
}
}
API Reference
GmsTrustedTime
Future<int?> getTrustedTimeMillis()
Returns the current UTC time as milliseconds since Unix epoch (January 1, 1970 00:00:00 UTC).
Returns null when:
- The device has not connected to the internet since the last boot (GMS has no time signal yet).
- Google Play Services is unavailable on the device.
Always handle null gracefully. A recommended pattern is to fall back to DateTime.now().millisecondsSinceEpoch for non-security-critical use cases.
How It Works
The plugin delegates to the native Android TrustedTimeClient from Google Play Services:
Flutter → MethodChannel → GmsTrustedTimePlugin.kt
→ TrustedTimeClient.computeCurrentUnixEpochMillis()
→ Google Play Services (synced with Google's time servers)
Google Play Services periodically syncs with Google's time infrastructure in the background. The plugin simply reads the cached, verified time — no extra network calls are made per request.
Reference: Google Play Services Time API
Requirements
- Android 5.0 (API level 21) or higher
- Google Play Services installed on device
- Internet connection required after each device boot (on first query)
License
MIT License — see LICENSE for details.