Description
I am creating a subscription with GraphQL, and I need to consume that subscription with Flutter, but I don't know how to do that on the Flutter side. But I can understand doing that on Postman.
Here are the steps to test a subscription on Postman:
- Connect to wss
- Send a
Message
by clickingSend
button. - Trigger any API, then the subscription will listen new data.
And here's the result for above steps.
And if I do these steps, the subscription will not work.
- Connect to wss
- Trigger any API, then the subscription will not listen any data.
And here's the result for above steps.
As u can see, even though connected to the wss, if i dont send the Message
by clicked the Send
button, the subscription will not work.
When I try to implement the subscription in Flutter side, seems only connected to the wss, here's the result.
flutter: Initialising connection
So my question is, how to send the Message
like from Postman but in Flutter side?
Here's the Message
data.
{
"id": "{{$randomUUID}}",
"payload": {
"data": "{\"query\":\"subscription updateCheckout { onUpdateCheckout(userId: \\\"{{userId}}\\\") { userId createdAt amount checkoutId maxAllowedAmount maxAvailableAmount message state trancheId }}\"}",
"extensions": {
"authorization": {
"Authorization": "{{cognitoIdToken}}",
"host": "{{apiHost}}"
}
}
},
"type": "start"
}
Here's the Schema
from AWS.
subscription MySubscription {
onUpdateCheckout(userId: $userId) {
createdAt
checkoutId
maxAllowedAmount
maxAvailableAmount
message
state
trancheId
}
}
And here's my Flutter code to impl the subscription.
Future<Map<String, dynamic>> subscription() async {
try {
final graphqlEndpoint = 'https://BASEURL/graphql';
final subscriptionEndpoint =
'wss://BASEURL/graphql/realtime?header=<EncodedHeader>&payload=e30=';
var currentToken = _token();
final HttpLink httpLink = HttpLink(
graphqlEndpoint,
defaultHeaders: {
'Authorization': "Bearer $currentToken",
'Sec-WebSocket-Protocol': GraphQLProtocol.graphqlWs,
},
);
final WebSocketLink webSocketLink = WebSocketLink(
subscriptionEndpoint,
config: SocketClientConfig(
autoReconnect: true,
serializer: AppSyncRequest(uuid: 'uuid', token: currentToken),
inactivityTimeout: const Duration(seconds: 60),
headers: kIsWeb
? null
: {
'Authorization': "Bearer $currentToken",
'Sec-WebSocket-Protocol': GraphQLProtocol.graphqlWs,
},
initialPayload: {
'Authorization': currentToken,
},
),
subProtocol: GraphQLProtocol.graphqlWs,
);
final AuthLink authLink =
AuthLink(getToken: () => 'Bearer $currentToken');
final Link linkSplitted = authLink.split(
(request) => request.isSubscription,
webSocketLink,
httpLink,
);
final graphQLCache = GraphQLCache();
final client = GraphQLClient(
link: linkSplitted,
cache: graphQLCache,
defaultPolicies: DefaultPolicies(
watchQuery: Policies(fetch: FetchPolicy.noCache),
query: Policies(fetch: FetchPolicy.noCache),
mutate: Policies(fetch: FetchPolicy.noCache),
subscribe: Policies(fetch: FetchPolicy.noCache),
),
alwaysRebroadcast: true,
);
const checkOutSubscription = r'''
subscription MySubscription {
onUpdateCheckout(userId: $userId) {
createdAt
checkoutId
maxAllowedAmount
maxAvailableAmount
message
state
trancheId
}
}
''';
final options = SubscriptionOptions(
document: gql(checkOutSubscription),
variables: {
"userId": "userId",
},
);
final result = client.subscribe(options);
Map<String, dynamic> data = {};
result.listen(
(event) {
// not triggered
data = event.data ?? {};
if (data.isNotEmpty) {
// not triggered
}
},
cancelOnError: true,
);
return Future.value(data);
} on Exception {
rethrow;
}
}