Skip to content

Commit 394506e

Browse files
authored
Merge pull request #185 from GetStream/remove-token-from-constructor
2 parents 3f8ab8c + 49a2133 commit 394506e

28 files changed

+867
-223
lines changed

example/lib/main.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ void main() {
1212
const _key = String.fromEnvironment('key');
1313
const _userToken = String.fromEnvironment('user_token');
1414

15-
final client = StreamFeedClient(
16-
_key,
17-
token: const Token(_userToken),
18-
);
15+
final client = StreamFeedClient(_key);
1916

2017
runApp(
2118
MyApp(

packages/stream_feed/CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
## 0.5.0: 12/01/2022
2+
3+
- BREAKING: we no longer accept a token in the constructor. This change is inspired by Stream Chat, and allows for use cases like multi account management. It allows to instantiate `StreamFeedClient` at the top of your widget tree for example, and connecting the user later.
4+
5+
```diff
6+
- client = StreamFeedClient(apiKey, token: frontendToken);
7+
+ client = StreamFeedClient(apiKey);
8+
+
9+
+ await client.setUser(
10+
+ const User(
11+
+ data: {
12+
+ 'name': 'John Doe',
13+
+ 'occupation': 'Software Engineer',
14+
+ 'gender': 'male'
15+
+ },
16+
+ ),
17+
+ frontendToken,
18+
+ );
19+
```
20+
121
## 0.4.0+3: 27/12/2021
222

323
- fix: call profile in setUser, so that currentUser data is not null

packages/stream_feed/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ final userToken = client.frontendToken('the-user-id');
6666
#### Client API init
6767

6868
```dart
69-
// Instantiate new client with a user token
70-
var client = StreamFeedClient(apiKey, token: Token('userToken'));
69+
// Instantiate new client and set the user token
70+
var client = StreamFeedClient(apiKey);
71+
72+
await client.setUser(user:user, token: frontendToken);
7173
```
7274

7375
### 🔮 Examples

packages/stream_feed/example/main.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ Future<void> main() async {
8686
// Client-side
8787
client = StreamFeedClient(
8888
apiKey,
89-
token: userToken,
9089
appId: appId,
9190
);
9291

@@ -339,7 +338,7 @@ Future<void> main() async {
339338
object: cheeseBurgerRef,
340339
));
341340

342-
client = StreamFeedClient(apiKey, token: frontendToken);
341+
client = StreamFeedClient(apiKey);
343342
// ensure the user data is stored on Stream
344343
await client.setUser(
345344
const User(

packages/stream_feed/lib/src/client/stream_feed_client.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ abstract class StreamFeedClient {
5757
/// {@endtemplate}
5858
factory StreamFeedClient(
5959
String apiKey, {
60-
Token? token,
6160
String? secret,
6261
String? appId,
6362
StreamHttpClientOptions? options,
@@ -69,7 +68,6 @@ abstract class StreamFeedClient {
6968
}) =>
7069
StreamFeedClientImpl(
7170
apiKey,
72-
userToken: token,
7371
secret: secret,
7472
appId: appId,
7573
options: options,

packages/stream_feed/lib/src/client/stream_feed_client_impl.dart

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ class StreamFeedClientImpl implements StreamFeedClient {
3838
StreamFeedClientImpl(
3939
this.apiKey, {
4040
this.secret,
41-
this.userToken, //TODO(sacha): remove this and call _ensureCredentials
42-
//in the getters instead (collections etc)
4341
this.appId,
4442
this.fayeUrl = 'wss://faye-us-east.stream-io-api.com/faye',
4543
this.runner = Runner.client,
@@ -48,7 +46,6 @@ class StreamFeedClientImpl implements StreamFeedClient {
4846
StreamAPI? api,
4947
StreamHttpClientOptions? options,
5048
}) {
51-
assert(_ensureCredentials(), '');
5249
_logger = Logger.detached('📜')..level = logLevel;
5350
_logger.onRecord.listen(logHandlerFunction ?? _defaultLogHandler);
5451
_logger.info('instantiating new client');
@@ -72,7 +69,8 @@ class StreamFeedClientImpl implements StreamFeedClient {
7269
case Runner.client:
7370
if (userToken == null) {
7471
throw AssertionError(
75-
'`userToken` must be provided while running on client-side',
72+
'`userToken` must be provided while running on client-side'
73+
'please make sure to call client.setUser',
7674
);
7775
}
7876
if (secret != null) {
@@ -146,6 +144,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
146144

147145
@override
148146
BatchOperationsClient get batch {
147+
assert(_ensureCredentials(), '');
149148
assert(
150149
runner == Runner.server,
151150
"You can't use batch operations client side",
@@ -154,29 +153,44 @@ class StreamFeedClientImpl implements StreamFeedClient {
154153
}
155154

156155
@override
157-
CollectionsClient get collections =>
158-
CollectionsClient(_api.collections, userToken: userToken, secret: secret);
156+
CollectionsClient get collections {
157+
assert(_ensureCredentials(), '');
158+
return CollectionsClient(_api.collections,
159+
userToken: userToken, secret: secret);
160+
}
159161

160162
@override
161-
ReactionsClient get reactions =>
162-
ReactionsClient(_api.reactions, userToken: userToken, secret: secret);
163+
ReactionsClient get reactions {
164+
assert(_ensureCredentials(), '');
165+
return ReactionsClient(_api.reactions,
166+
userToken: userToken, secret: secret);
167+
}
163168

164169
@override
165-
PersonalizationClient get personalization =>
166-
PersonalizationClient(_api.personalization,
167-
userToken: userToken, secret: secret);
170+
PersonalizationClient get personalization {
171+
assert(_ensureCredentials(), '');
172+
return PersonalizationClient(_api.personalization,
173+
userToken: userToken, secret: secret);
174+
}
168175

169176
@override
170-
StreamUser user(String userId) =>
171-
StreamUser(_api.users, userId, userToken: userToken, secret: secret);
177+
StreamUser user(String userId) {
178+
// assert(_ensureCredentials(), '');
179+
return StreamUser(_api.users, userId, userToken: userToken, secret: secret);
180+
}
172181

173182
@override
174-
FileStorageClient get files =>
175-
FileStorageClient(_api.files, userToken: userToken, secret: secret);
183+
FileStorageClient get files {
184+
assert(_ensureCredentials(), '');
185+
return FileStorageClient(_api.files, userToken: userToken, secret: secret);
186+
}
176187

177188
@override
178-
ImageStorageClient get images =>
179-
ImageStorageClient(_api.images, userToken: userToken, secret: secret);
189+
ImageStorageClient get images {
190+
assert(_ensureCredentials(), '');
191+
return ImageStorageClient(_api.images,
192+
userToken: userToken, secret: secret);
193+
}
180194

181195
Future<Subscription> _feedSubscriber(
182196
Token token,
@@ -219,6 +233,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
219233
String? userId,
220234
Token? userToken,
221235
]) {
236+
assert(_ensureCredentials(), '');
222237
final id = FeedId(slug, _getUserId(userId));
223238
return AggregatedFeed(
224239
id,
@@ -235,6 +250,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
235250
String? userId,
236251
Token? userToken,
237252
]) {
253+
assert(_ensureCredentials(), '');
238254
final id = FeedId(slug, _getUserId(userId));
239255
return FlatFeed(
240256
id,
@@ -251,6 +267,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
251267
String? userId,
252268
Token? userToken,
253269
]) {
270+
assert(_ensureCredentials(), '');
254271
final id = FeedId(slug, _getUserId(userId));
255272
return NotificationFeed(
256273
id,
@@ -266,6 +283,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
266283
String userId, {
267284
DateTime? expiresAt,
268285
}) {
286+
assert(_ensureCredentials(), '');
269287
assert(
270288
runner == Runner.server,
271289
"You can't use the `frontendToken` method client side",
@@ -276,6 +294,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
276294

277295
@override
278296
Future<OpenGraphData> og(String targetUrl) {
297+
assert(_ensureCredentials(), '');
279298
final token = userToken ?? TokenHelper.buildOpenGraphToken(secret!);
280299
return _api.openGraph(token, targetUrl);
281300
}
@@ -286,6 +305,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
286305
Map<String, Object?> data, {
287306
bool getOrCreate = false,
288307
}) {
308+
assert(_ensureCredentials(), '');
289309
if (runner == Runner.client) {
290310
_logger.warning('We advice using `client.createUser` only server-side');
291311
}
@@ -296,16 +316,19 @@ class StreamFeedClientImpl implements StreamFeedClient {
296316

297317
@override
298318
Future<User> getUser(String id, {bool withFollowCounts = false}) {
319+
assert(_ensureCredentials(), '');
299320
if (runner == Runner.client) {
300321
_logger.warning('We advice using `client.getUser` only server-side');
301322
}
323+
302324
final token =
303325
userToken ?? TokenHelper.buildUsersToken(secret!, TokenAction.read);
304326
return _api.users.get(token, id, withFollowCounts: withFollowCounts);
305327
}
306328

307329
@override
308330
Future<User> updateUser(String id, Map<String, Object?> data) {
331+
assert(_ensureCredentials(), '');
309332
if (runner == Runner.client) {
310333
_logger.warning('We advice using `client.updateUser` only server-side');
311334
}
@@ -316,6 +339,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
316339

317340
@override
318341
Future<void> deleteUser(String id) {
342+
assert(_ensureCredentials(), '');
319343
if (runner == Runner.client) {
320344
_logger.warning('We advice using `client.deleteUser` only server-side');
321345
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import 'package:dio/dio.dart';
2+
import 'package:stream_feed/src/core/error/stream_feeds_error.dart';
3+
4+
/// Error class specific to StreamFeed and Dio
5+
class StreamFeedsDioError extends DioError {
6+
/// Initialize a stream feed dio error
7+
StreamFeedsDioError({
8+
required this.error,
9+
required RequestOptions requestOptions,
10+
Response? response,
11+
DioErrorType type = DioErrorType.other,
12+
}) : super(
13+
error: error,
14+
requestOptions: requestOptions,
15+
response: response,
16+
type: type,
17+
);
18+
19+
@override
20+
final StreamFeedsNetworkError error;
21+
}

packages/stream_feed/lib/src/core/error/stream_feeds_error.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:convert';
2+
13
import 'package:dio/dio.dart';
24
import 'package:equatable/equatable.dart';
35
import 'package:stream_feed/src/core/api/responses.dart';
@@ -22,12 +24,12 @@ class StreamFeedsError with EquatableMixin implements Exception {
2224
class StreamFeedsNetworkError extends StreamFeedsError {
2325
/// Builds a [StreamFeedsNetworkError].
2426
StreamFeedsNetworkError(
25-
FeedsError error, {
27+
FeedsError errorCode, {
2628
int? statusCode,
2729
this.data,
28-
}) : code = error.code,
30+
}) : code = errorCode.code,
2931
statusCode = statusCode ?? data?.statusCode,
30-
super(error.message);
32+
super(errorCode.message);
3133

3234
StreamFeedsNetworkError.raw({
3335
required this.code,
@@ -40,7 +42,7 @@ class StreamFeedsNetworkError extends StreamFeedsError {
4042
factory StreamFeedsNetworkError.fromDioError(DioError error) {
4143
final response = error.response;
4244
ErrorResponse? errorResponse;
43-
final data = response?.data;
45+
final data = json.decode(response?.data);
4446
if (data != null) {
4547
errorResponse = ErrorResponse.fromJson(data);
4648
}
@@ -64,12 +66,10 @@ class StreamFeedsNetworkError extends StreamFeedsError {
6466

6567
StackTrace? _stackTrace;
6668

67-
///
6869
set stackTrace(StackTrace? stack) => _stackTrace = stack;
6970

7071
FeedsError? get errorCode => feedsErrorCodeFromCode(code);
7172

72-
///
7373
bool get isRetriable => data == null;
7474

7575
@override

packages/stream_feed/lib/src/core/http/stream_http_client.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:dio/dio.dart' hide Headers;
22
import 'package:logging/logging.dart';
33
import 'package:meta/meta.dart';
44
import 'package:stream_feed/src/core/error/feeds_error_code.dart';
5+
import 'package:stream_feed/src/core/error/stream_feeds_dio_error.dart';
56
import 'package:stream_feed/src/core/error/stream_feeds_error.dart';
67
import 'package:stream_feed/src/core/http/interceptor/logging_interceptor.dart';
78
import 'package:stream_feed/src/core/http/location.dart';
@@ -70,14 +71,16 @@ class StreamHttpClient {
7071
@visibleForTesting
7172
final Dio httpClient;
7273

73-
StreamFeedsNetworkError _parseError(DioError dioError) {
74-
StreamFeedsNetworkError feedsError;
75-
if (dioError is FeedsError) {
76-
feedsError = dioError.error;
74+
StreamFeedsNetworkError _parseError(DioError err) {
75+
StreamFeedsNetworkError error;
76+
// locally thrown dio error
77+
if (err is StreamFeedsDioError) {
78+
error = err.error;
7779
} else {
78-
feedsError = StreamFeedsNetworkError.fromDioError(dioError);
80+
// real network request dio error
81+
error = StreamFeedsNetworkError.fromDioError(err);
7982
}
80-
return feedsError..stackTrace = dioError.stackTrace;
83+
return error..stackTrace = err.stackTrace;
8184
}
8285

8386
/// Combines the base url with the [relativeUrl]

packages/stream_feed/lib/version.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/// Current package version
22
/// Used in [HttpClient] to build the `x-stream-client` header
3-
const String packageVersion = '0.4.0+3';
3+
const String packageVersion = '0.5.0';

packages/stream_feed/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: stream_feed
22
description: Stream Feed official Dart SDK. Build your own feed experience using Dart and Flutter.
3-
version: 0.4.0+3
3+
version: 0.5.0
44
repository: https://github.com/GetStream/stream-feed-flutter
55
issue_tracker: https://github.com/GetStream/stream-feed-flutter/issues
66
homepage: https://getstream.io/

0 commit comments

Comments
 (0)