-
-
Notifications
You must be signed in to change notification settings - Fork 641
Open
Labels
⚡ websocketWeb Socket RelatedWeb Socket RelatedPriority: HighHigh priority to include it inside next releaseHigh priority to include it inside next release
Milestone
Description
I cannot seem to be able to use GraphQL subscriptions with my AWS server, by using Cognito authentication.
Queries and mutations work fine as far as I can tell, but I couldn't find how to connect to the amplify websocket.
Here is the code I tried, based on this comment: #682 (comment) (which I had to edit because Cognito tokens are not static)
import 'dart:async';
import 'dart:convert';
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:flutter/material.dart';
import 'package:gql/language.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
String toBase64(Map data) => base64.encode(utf8.encode(jsonEncode(data)));
const apiId = "XXX";
const zone = "eu-west-1";
class AppSyncRequest extends RequestSerializer {
final Map<String, dynamic> authHeader;
const AppSyncRequest({
required this.authHeader,
});
@override
Map<String, dynamic> serializeRequest(Request request) => {
"data": jsonEncode({
"query": printNode(request.operation.document),
"variables": request.variables,
}),
"extensions": {
"authorization": authHeader,
}
};
}
ValueNotifier<GraphQLClient> buildClient() {
Future<String?> _fetchSession() async {
try {
final session = await Amplify.Auth.fetchAuthSession(
options: CognitoSessionOptions(getAWSCredentials: true))
as CognitoAuthSession;
if (!session.isSignedIn) {
return null;
}
return session.userPoolTokens?.accessToken;
} on AuthException catch (e) {
debugPrintStack(label: e.toString());
}
return null;
}
Future<String?> _getIdToken() async {
try {
final session = await Amplify.Auth.fetchAuthSession(
options: CognitoSessionOptions(getAWSCredentials: true))
as CognitoAuthSession;
if (!session.isSignedIn) {
return null;
}
return session.userPoolTokens?.idToken;
} on AuthException catch (e) {
debugPrintStack(label: e.toString());
}
return null;
}
final HttpLink httpLink =
HttpLink("https://$apiId.appsync-api.$zone.amazonaws.com/graphql");
final WebSocketLink wsLink = WebSocketLink(
'wss://$apiId.appsync-realtime-api.$zone.amazonaws.com/graphql',
config: SocketClientConfig(
initialPayload: () async {
final token = await _fetchSession();
return {
"headers": {
"Authorization": '$token',
"host": "$apiId.appsync-api.$zone.amazonaws.com",
},
};
},
),
);
final AuthLink authLink = AuthLink(
getToken: _fetchSession,
);
// final Link link = authLink.concat(httpLink).concat(wsLink);
final Link link = Link.split((request) => request.isSubscription,
authLink.concat(wsLink), authLink.concat(httpLink));
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: link,
defaultPolicies:
DefaultPolicies(query: Policies(fetch: FetchPolicy.cacheAndNetwork)),
cache: GraphQLCache(
partialDataPolicy: PartialDataCachePolicy.accept,
store: HiveStore(),
),
),
);
return client;
}
class ClientProvider extends StatefulWidget {
final Widget child;
const ClientProvider({
Key? key,
required this.child,
}) : super(key: key);
@override
State<ClientProvider> createState() => _ClientProviderState();
}
class _ClientProviderState extends State<ClientProvider> {
@override
Widget build(BuildContext context) {
return GraphQLProvider(
client: buildClient(),
child: widget.child,
);
}
}- If I use the
Link.split()method, my console is spammed withflutter: Disconnected from websocket. - If I use the
Link.concat()method, I get a HttpLinkServerException:GraphQLError(message: Subscriptions over MQTT is not supported., locations: null, path: null, extensions: null)
Naturally in both ways my Subscription widget doesn't work (infinite loading state).
Device / execution context
- Executed on macOS 12.4 (MacBook Pro M1 Pro)
- iOS 15.5
- Flutter 3.0.2
- graphql_flutter 5.1.0
- amplify_flutter 0.5.1
- amplify_api 0.5.1
- XCode 13.4.1
- VSCode 1.68.1
naedx
Metadata
Metadata
Assignees
Labels
⚡ websocketWeb Socket RelatedWeb Socket RelatedPriority: HighHigh priority to include it inside next releaseHigh priority to include it inside next release