Skip to content

Commit

Permalink
Merge pull request #185 from GetStream/remove-token-from-constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
sachaarbonel authored Jan 12, 2022
2 parents 3f8ab8c + 49a2133 commit 394506e
Show file tree
Hide file tree
Showing 28 changed files with 867 additions and 223 deletions.
5 changes: 1 addition & 4 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ void main() {
const _key = String.fromEnvironment('key');
const _userToken = String.fromEnvironment('user_token');

final client = StreamFeedClient(
_key,
token: const Token(_userToken),
);
final client = StreamFeedClient(_key);

runApp(
MyApp(
Expand Down
20 changes: 20 additions & 0 deletions packages/stream_feed/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
## 0.5.0: 12/01/2022

- 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.

```diff
- client = StreamFeedClient(apiKey, token: frontendToken);
+ client = StreamFeedClient(apiKey);
+
+ await client.setUser(
+ const User(
+ data: {
+ 'name': 'John Doe',
+ 'occupation': 'Software Engineer',
+ 'gender': 'male'
+ },
+ ),
+ frontendToken,
+ );
```

## 0.4.0+3: 27/12/2021

- fix: call profile in setUser, so that currentUser data is not null
Expand Down
6 changes: 4 additions & 2 deletions packages/stream_feed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,10 @@ final userToken = client.frontendToken('the-user-id');
#### Client API init

```dart
// Instantiate new client with a user token
var client = StreamFeedClient(apiKey, token: Token('userToken'));
// Instantiate new client and set the user token
var client = StreamFeedClient(apiKey);
await client.setUser(user:user, token: frontendToken);
```

### 🔮 Examples
Expand Down
3 changes: 1 addition & 2 deletions packages/stream_feed/example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ Future<void> main() async {
// Client-side
client = StreamFeedClient(
apiKey,
token: userToken,
appId: appId,
);

Expand Down Expand Up @@ -339,7 +338,7 @@ Future<void> main() async {
object: cheeseBurgerRef,
));

client = StreamFeedClient(apiKey, token: frontendToken);
client = StreamFeedClient(apiKey);
// ensure the user data is stored on Stream
await client.setUser(
const User(
Expand Down
2 changes: 0 additions & 2 deletions packages/stream_feed/lib/src/client/stream_feed_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ abstract class StreamFeedClient {
/// {@endtemplate}
factory StreamFeedClient(
String apiKey, {
Token? token,
String? secret,
String? appId,
StreamHttpClientOptions? options,
Expand All @@ -69,7 +68,6 @@ abstract class StreamFeedClient {
}) =>
StreamFeedClientImpl(
apiKey,
userToken: token,
secret: secret,
appId: appId,
options: options,
Expand Down
58 changes: 41 additions & 17 deletions packages/stream_feed/lib/src/client/stream_feed_client_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ class StreamFeedClientImpl implements StreamFeedClient {
StreamFeedClientImpl(
this.apiKey, {
this.secret,
this.userToken, //TODO(sacha): remove this and call _ensureCredentials
//in the getters instead (collections etc)
this.appId,
this.fayeUrl = 'wss://faye-us-east.stream-io-api.com/faye',
this.runner = Runner.client,
Expand All @@ -48,7 +46,6 @@ class StreamFeedClientImpl implements StreamFeedClient {
StreamAPI? api,
StreamHttpClientOptions? options,
}) {
assert(_ensureCredentials(), '');
_logger = Logger.detached('📜')..level = logLevel;
_logger.onRecord.listen(logHandlerFunction ?? _defaultLogHandler);
_logger.info('instantiating new client');
Expand All @@ -72,7 +69,8 @@ class StreamFeedClientImpl implements StreamFeedClient {
case Runner.client:
if (userToken == null) {
throw AssertionError(
'`userToken` must be provided while running on client-side',
'`userToken` must be provided while running on client-side'
'please make sure to call client.setUser',
);
}
if (secret != null) {
Expand Down Expand Up @@ -146,6 +144,7 @@ class StreamFeedClientImpl implements StreamFeedClient {

@override
BatchOperationsClient get batch {
assert(_ensureCredentials(), '');
assert(
runner == Runner.server,
"You can't use batch operations client side",
Expand All @@ -154,29 +153,44 @@ class StreamFeedClientImpl implements StreamFeedClient {
}

@override
CollectionsClient get collections =>
CollectionsClient(_api.collections, userToken: userToken, secret: secret);
CollectionsClient get collections {
assert(_ensureCredentials(), '');
return CollectionsClient(_api.collections,
userToken: userToken, secret: secret);
}

@override
ReactionsClient get reactions =>
ReactionsClient(_api.reactions, userToken: userToken, secret: secret);
ReactionsClient get reactions {
assert(_ensureCredentials(), '');
return ReactionsClient(_api.reactions,
userToken: userToken, secret: secret);
}

@override
PersonalizationClient get personalization =>
PersonalizationClient(_api.personalization,
userToken: userToken, secret: secret);
PersonalizationClient get personalization {
assert(_ensureCredentials(), '');
return PersonalizationClient(_api.personalization,
userToken: userToken, secret: secret);
}

@override
StreamUser user(String userId) =>
StreamUser(_api.users, userId, userToken: userToken, secret: secret);
StreamUser user(String userId) {
// assert(_ensureCredentials(), '');
return StreamUser(_api.users, userId, userToken: userToken, secret: secret);
}

@override
FileStorageClient get files =>
FileStorageClient(_api.files, userToken: userToken, secret: secret);
FileStorageClient get files {
assert(_ensureCredentials(), '');
return FileStorageClient(_api.files, userToken: userToken, secret: secret);
}

@override
ImageStorageClient get images =>
ImageStorageClient(_api.images, userToken: userToken, secret: secret);
ImageStorageClient get images {
assert(_ensureCredentials(), '');
return ImageStorageClient(_api.images,
userToken: userToken, secret: secret);
}

Future<Subscription> _feedSubscriber(
Token token,
Expand Down Expand Up @@ -219,6 +233,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
String? userId,
Token? userToken,
]) {
assert(_ensureCredentials(), '');
final id = FeedId(slug, _getUserId(userId));
return AggregatedFeed(
id,
Expand All @@ -235,6 +250,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
String? userId,
Token? userToken,
]) {
assert(_ensureCredentials(), '');
final id = FeedId(slug, _getUserId(userId));
return FlatFeed(
id,
Expand All @@ -251,6 +267,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
String? userId,
Token? userToken,
]) {
assert(_ensureCredentials(), '');
final id = FeedId(slug, _getUserId(userId));
return NotificationFeed(
id,
Expand All @@ -266,6 +283,7 @@ class StreamFeedClientImpl implements StreamFeedClient {
String userId, {
DateTime? expiresAt,
}) {
assert(_ensureCredentials(), '');
assert(
runner == Runner.server,
"You can't use the `frontendToken` method client side",
Expand All @@ -276,6 +294,7 @@ class StreamFeedClientImpl implements StreamFeedClient {

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

@override
Future<User> getUser(String id, {bool withFollowCounts = false}) {
assert(_ensureCredentials(), '');
if (runner == Runner.client) {
_logger.warning('We advice using `client.getUser` only server-side');
}

final token =
userToken ?? TokenHelper.buildUsersToken(secret!, TokenAction.read);
return _api.users.get(token, id, withFollowCounts: withFollowCounts);
}

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

@override
Future<void> deleteUser(String id) {
assert(_ensureCredentials(), '');
if (runner == Runner.client) {
_logger.warning('We advice using `client.deleteUser` only server-side');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:dio/dio.dart';
import 'package:stream_feed/src/core/error/stream_feeds_error.dart';

/// Error class specific to StreamFeed and Dio
class StreamFeedsDioError extends DioError {
/// Initialize a stream feed dio error
StreamFeedsDioError({
required this.error,
required RequestOptions requestOptions,
Response? response,
DioErrorType type = DioErrorType.other,
}) : super(
error: error,
requestOptions: requestOptions,
response: response,
type: type,
);

@override
final StreamFeedsNetworkError error;
}
12 changes: 6 additions & 6 deletions packages/stream_feed/lib/src/core/error/stream_feeds_error.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:equatable/equatable.dart';
import 'package:stream_feed/src/core/api/responses.dart';
Expand All @@ -22,12 +24,12 @@ class StreamFeedsError with EquatableMixin implements Exception {
class StreamFeedsNetworkError extends StreamFeedsError {
/// Builds a [StreamFeedsNetworkError].
StreamFeedsNetworkError(
FeedsError error, {
FeedsError errorCode, {
int? statusCode,
this.data,
}) : code = error.code,
}) : code = errorCode.code,
statusCode = statusCode ?? data?.statusCode,
super(error.message);
super(errorCode.message);

StreamFeedsNetworkError.raw({
required this.code,
Expand All @@ -40,7 +42,7 @@ class StreamFeedsNetworkError extends StreamFeedsError {
factory StreamFeedsNetworkError.fromDioError(DioError error) {
final response = error.response;
ErrorResponse? errorResponse;
final data = response?.data;
final data = json.decode(response?.data);
if (data != null) {
errorResponse = ErrorResponse.fromJson(data);
}
Expand All @@ -64,12 +66,10 @@ class StreamFeedsNetworkError extends StreamFeedsError {

StackTrace? _stackTrace;

///
set stackTrace(StackTrace? stack) => _stackTrace = stack;

FeedsError? get errorCode => feedsErrorCodeFromCode(code);

///
bool get isRetriable => data == null;

@override
Expand Down
15 changes: 9 additions & 6 deletions packages/stream_feed/lib/src/core/http/stream_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:dio/dio.dart' hide Headers;
import 'package:logging/logging.dart';
import 'package:meta/meta.dart';
import 'package:stream_feed/src/core/error/feeds_error_code.dart';
import 'package:stream_feed/src/core/error/stream_feeds_dio_error.dart';
import 'package:stream_feed/src/core/error/stream_feeds_error.dart';
import 'package:stream_feed/src/core/http/interceptor/logging_interceptor.dart';
import 'package:stream_feed/src/core/http/location.dart';
Expand Down Expand Up @@ -70,14 +71,16 @@ class StreamHttpClient {
@visibleForTesting
final Dio httpClient;

StreamFeedsNetworkError _parseError(DioError dioError) {
StreamFeedsNetworkError feedsError;
if (dioError is FeedsError) {
feedsError = dioError.error;
StreamFeedsNetworkError _parseError(DioError err) {
StreamFeedsNetworkError error;
// locally thrown dio error
if (err is StreamFeedsDioError) {
error = err.error;
} else {
feedsError = StreamFeedsNetworkError.fromDioError(dioError);
// real network request dio error
error = StreamFeedsNetworkError.fromDioError(err);
}
return feedsError..stackTrace = dioError.stackTrace;
return error..stackTrace = err.stackTrace;
}

/// Combines the base url with the [relativeUrl]
Expand Down
2 changes: 1 addition & 1 deletion packages/stream_feed/lib/version.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/// Current package version
/// Used in [HttpClient] to build the `x-stream-client` header
const String packageVersion = '0.4.0+3';
const String packageVersion = '0.5.0';
2 changes: 1 addition & 1 deletion packages/stream_feed/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: stream_feed
description: Stream Feed official Dart SDK. Build your own feed experience using Dart and Flutter.
version: 0.4.0+3
version: 0.5.0
repository: https://github.com/GetStream/stream-feed-flutter
issue_tracker: https://github.com/GetStream/stream-feed-flutter/issues
homepage: https://getstream.io/
Expand Down
Loading

0 comments on commit 394506e

Please sign in to comment.