library dart_firebase.impl.common.http; import 'dart:async'; import '../../../api.dart'; const String _defaultAppName = "[DEFAULT]"; abstract class FirestoreHttpClient implements FirestoreClient { FirestoreHttpClient( this.email, this.password, this.app, this.token, this.endpoints); @override final String email; @override final String password; @override final App app; @override final FirestoreApiEndpoints endpoints; @override FirestoreAccessToken token; bool isCurrentTokenValid(bool refreshable) { if (refreshable) { var now = DateTime.now(); return token.expiresAt.difference(now).abs().inSeconds >= 60; } return true; } @override bool get isAuthorized => isCurrentTokenValid(true); @override Future login() async { if (!isCurrentTokenValid(false)) { var result = await sendHttpRequest(endpoints.getAuthUrl(app), body: { "email": email, "password": password, "returnSecureToken": true, }, needsToken: false); token = FirestoreJsonAccessToken(result, DateTime.now()); return; } var result = await sendHttpRequest(endpoints.getRefreshUrl(app), body: { "grant_type": "refresh_token", "refresh_token": token.refreshToken }, needsToken: false); token = FirestoreJsonAccessToken(result, DateTime.now()); } @override Future> listDocumentSnapshots(String path) async { var list = []; var result = await (getJsonList("$path", extract: 'documents') as FutureOr>); for (var item in result) { list.add(new DocumentSnapshot(this, item)); } return list; } @override CollectionReference collection(String path) { return CollectionReference(this, path.split('/')); } @override DocumentReference document(String path) { return DocumentReference(this, path.split('/')); } @override Future getDocumentSnapshot(String path) async { final _data = await getJsonMap("$path", extract: null); return DocumentSnapshot(this, _asStringKeyedMap(_data)); } Future?> getJsonMap(String url, {Map? body, String? extract = "response", bool standard = true}) async { return (await sendHttpRequest(_apiUrl(url, standard), body: body, extract: extract)) as Map?; } Future?> getJsonList(String url, {Map? body, String extract = "response", bool standard = true}) async { return (await sendHttpRequest(_apiUrl(url, standard), body: body, extract: extract)) as List?; } Future sendHttpRequest(Uri uri, {bool needsToken = true, String? extract, Map? body}); Uri _apiUrl(String path, bool standard) { path = standard ? "$path" : path; var uri = endpoints.getFirestoreUrl(app).resolve(path); return uri; } } Map? _asStringKeyedMap(Map? map) { if (map == null) return null; if (map is Map) { return map; } else { return Map.from(map); } }