Skip to content

Commit fa459ff

Browse files
committed
Fixed checks
1 parent 628294b commit fa459ff

File tree

6 files changed

+49
-34
lines changed

6 files changed

+49
-34
lines changed

packages/firebase_data_connect/firebase_data_connect/lib/src/common/common_library.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ library firebase_data_connect_common;
1717
import 'dart:convert';
1818

1919
import 'package:firebase_app_check/firebase_app_check.dart';
20-
import 'package:firebase_auth/firebase_auth.dart';
2120

2221
part 'dataconnect_error.dart';
2322
part 'dataconnect_options.dart';

packages/firebase_data_connect/firebase_data_connect/lib/src/core/ref.dart

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,29 @@ abstract class OperationRef<Data, Variables> {
4242
DataConnectTransport _transport;
4343
Deserializer<Data> deserializer;
4444
Serializer<Variables> serializer;
45+
String? _lastToken;
4546

4647
FirebaseDataConnect dataConnect;
4748

4849
Future<OperationResult<Data, Variables>> execute() {
49-
return this._executeWithRetry(true);
50+
return this._executeWithRetry();
5051
}
5152

52-
Future<OperationResult<Data, Variables>> _executeOperation(bool forceRefresh);
53+
Future<OperationResult<Data, Variables>> _executeOperation(String? token);
5354

54-
Future<OperationResult<Data, Variables>> _executeWithRetry(bool retry) async {
55+
Future<OperationResult<Data, Variables>> _executeWithRetry() async {
56+
String? newToken =
57+
await this.dataConnect.auth?.currentUser?.getIdToken(false);
58+
bool shouldRetry = newToken != null && _lastToken != newToken;
59+
_lastToken = newToken;
5560
try {
56-
OperationResult<Data, Variables> r = await this._executeOperation(!retry);
61+
OperationResult<Data, Variables> r =
62+
await this._executeOperation(newToken);
5763
return r;
5864
} on DataConnectError catch (e) {
59-
if (retry && e.code == DataConnectErrorCode.unauthorized.toString()) {
60-
return this._executeWithRetry(false);
65+
if (shouldRetry &&
66+
e.code == DataConnectErrorCode.unauthorized.toString()) {
67+
return this._executeWithRetry();
6168
} else {
6269
throw e;
6370
}
@@ -132,10 +139,7 @@ class QueryRef<Data, Variables> extends OperationRef<Data, Variables> {
132139

133140
QueryManager _queryManager;
134141

135-
Future<QueryResult<Data, Variables>> _executeOperation(
136-
bool forceRefresh) async {
137-
String? token =
138-
await this.dataConnect.auth?.currentUser?.getIdToken(forceRefresh);
142+
Future<QueryResult<Data, Variables>> _executeOperation(String? token) async {
139143
try {
140144
Data data = await _transport.invokeQuery<Data, Variables>(
141145
operationName, deserializer, serializer, variables, token);
@@ -157,7 +161,7 @@ class QueryRef<Data, Variables> extends OperationRef<Data, Variables> {
157161
.cast<QueryResult<Data, Variables>>();
158162
if (_queryManager.containsQuery(operationName, variables, varsSerialized)) {
159163
try {
160-
this._executeWithRetry(true);
164+
this._executeWithRetry();
161165
} catch (_) {
162166
// Call to `execute` should properly pass the error to the Stream.
163167
log("Error thrown by execute. The error will propagate via onError.");
@@ -179,9 +183,7 @@ class MutationRef<Data, Variables> extends OperationRef<Data, Variables> {
179183
variables);
180184
@override
181185
Future<OperationResult<Data, Variables>> _executeOperation(
182-
bool forceRefresh) async {
183-
String? token =
184-
await this.dataConnect.auth?.currentUser?.getIdToken(forceRefresh);
186+
String? token) async {
185187
Data data = await _transport.invokeMutation<Data, Variables>(
186188
operationName, deserializer, serializer, variables, token);
187189
return OperationResult(dataConnect, data, this);

packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_library.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import 'dart:convert';
1818
import 'dart:developer';
1919

2020
import 'package:firebase_app_check/firebase_app_check.dart';
21-
import 'package:firebase_auth/firebase_auth.dart';
2221
import 'package:flutter/foundation.dart';
2322
import 'package:http/http.dart' as http;
2423

packages/firebase_data_connect/firebase_data_connect/lib/src/network/rest_transport.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,13 @@ class RestTransport implements DataConnectTransport {
6464

6565
/// Invokes the current operation, whether its a query or mutation.
6666
Future<Data> invokeOperation<Data, Variables>(
67-
String queryName,
68-
Deserializer<Data> deserializer,
69-
Serializer<Variables>? serializer,
70-
Variables? vars,
71-
String? authToken,
72-
String endpoint) async {
67+
String queryName,
68+
String endpoint,
69+
Deserializer<Data> deserializer,
70+
Serializer<Variables>? serializer,
71+
Variables? vars,
72+
String? authToken,
73+
) async {
7374
String project = options.projectId;
7475
String location = options.location;
7576
String service = options.serviceId;
@@ -146,7 +147,7 @@ class RestTransport implements DataConnectTransport {
146147
Variables? vars,
147148
String? token) async {
148149
return invokeOperation(
149-
queryName, deserializer, serializer, vars, token, 'executeQuery');
150+
queryName, 'executeQuery', deserializer, serializer, vars, token);
150151
}
151152

152153
/// Invokes mutation REST endpoint.
@@ -158,7 +159,7 @@ class RestTransport implements DataConnectTransport {
158159
Variables? vars,
159160
String? token) async {
160161
return invokeOperation(
161-
queryName, deserializer, serializer, vars, token, 'executeMutation');
162+
queryName, 'executeMutation', deserializer, serializer, vars, token);
162163
}
163164
}
164165

packages/firebase_data_connect/firebase_data_connect/test/src/core/ref_test.dart

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,20 @@ class MockDataConnectTransport extends Mock implements DataConnectTransport {}
3232

3333
class MockFirebaseDataConnect extends Mock implements FirebaseDataConnect {}
3434

35-
class MockFirebaseAuth extends Mock implements FirebaseAuth {}
35+
class DCMockUser extends Mock implements User {
36+
int count = 0;
37+
List<String?> tokens = ['invalid-token', 'valid-token'];
38+
@override
39+
Future<String?> getIdToken([bool forceRefresh = false]) {
40+
// First return an invalid token, then return a valid token
41+
return Future.value(tokens[count++]);
42+
}
43+
}
44+
45+
class MockFirebaseAuth extends Mock implements FirebaseAuth {
46+
@override
47+
User? get currentUser => DCMockUser();
48+
}
3649

3750
class MockQueryManager extends Mock implements QueryManager {}
3851

@@ -111,7 +124,9 @@ void main() {
111124
late Deserializer<String> deserializer;
112125

113126
setUp(() {
127+
print('setting up');
114128
mockDataConnect = MockFirebaseDataConnect();
129+
when(mockDataConnect.auth).thenReturn(MockFirebaseAuth());
115130
mockHttpClient = MockClient();
116131
transport = RestTransport(
117132
TransportOptions('testhost', 443, true),
@@ -127,15 +142,14 @@ void main() {
127142
);
128143
transport.setHttp(mockHttpClient);
129144
mockDataConnect.transport = transport;
130-
mockDataConnect.auth = MockFirebaseAuth();
131145
});
132146
test(
133147
'query should forceRefresh on ID token if the first request is unauthorized',
134148
() async {
135149
final mockResponse = http.Response('{"error": "Unauthorized"}', 401);
136150
final mockResponseSuccess = http.Response('{"success": true}', 200);
137-
int count = 0;
138151
final deserializer = (String data) => 'Deserialized Data';
152+
int count = 0;
139153
QueryRef ref = QueryRef(mockDataConnect, 'operation', transport,
140154
deserializer, QueryManager(mockDataConnect), emptySerializer, null);
141155

packages/firebase_data_connect/firebase_data_connect/test/src/network/rest_transport_test.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,11 @@ void main() {
9696

9797
final result = await transport.invokeOperation(
9898
'testQuery',
99+
'executeQuery',
99100
deserializer,
100101
null,
101102
null,
102103
null,
103-
'executeQuery',
104104
);
105105

106106
expect(result, 'Deserialized Data');
@@ -117,7 +117,7 @@ void main() {
117117

118118
expect(
119119
() => transport.invokeOperation(
120-
'testQuery', deserializer, null, null, null, 'executeQuery'),
120+
'testQuery', 'executeQuery', deserializer, null, null, null),
121121
throwsA(isA<DataConnectError>()),
122122
);
123123
});
@@ -133,7 +133,7 @@ void main() {
133133

134134
expect(
135135
() => transport.invokeOperation(
136-
'testQuery', deserializer, null, null, null, 'executeQuery'),
136+
'testQuery', 'executeQuery', deserializer, null, null, null),
137137
throwsA(isA<DataConnectError>()),
138138
);
139139
});
@@ -195,8 +195,8 @@ void main() {
195195

196196
final deserializer = (String data) => 'Deserialized Data';
197197

198-
await transport.invokeOperation('testQuery', deserializer, null, null,
199-
'authToken123', 'executeQuery');
198+
await transport.invokeOperation('testQuery', 'executeQuery', deserializer,
199+
null, null, 'authToken123');
200200

201201
verify(mockHttpClient.post(
202202
any,
@@ -222,7 +222,7 @@ void main() {
222222
final deserializer = (String data) => 'Deserialized Data';
223223

224224
await transport.invokeOperation(
225-
'testQuery', deserializer, null, null, null, 'executeQuery');
225+
'testQuery', 'executeQuery', deserializer, null, null, null);
226226

227227
verify(mockHttpClient.post(
228228
any,
@@ -257,7 +257,7 @@ void main() {
257257

258258
expect(
259259
() => transport.invokeOperation(
260-
'testQuery', deserializer, null, null, null, 'executeQuery'),
260+
'testQuery', 'executeQuery', deserializer, null, null, null),
261261
throwsA(isA<DataConnectError>()),
262262
);
263263
});

0 commit comments

Comments
 (0)