File tree Expand file tree Collapse file tree 2 files changed +42
-3
lines changed
packages/firebase_data_connect/firebase_data_connect Expand file tree Collapse file tree 2 files changed +42
-3
lines changed Original file line number Diff line number Diff line change @@ -116,11 +116,12 @@ class RestTransport implements DataConnectTransport {
116116 headers: headers,
117117 );
118118 Map <String , dynamic > bodyJson =
119- jsonDecode (r.body ) as Map <String , dynamic >;
119+ jsonDecode (utf8. decode (r.bodyBytes) ) as Map <String , dynamic >;
120120
121121 if (r.statusCode != 200 ) {
122- String message =
123- bodyJson.containsKey ('message' ) ? bodyJson['message' ]! : r.body;
122+ String message = bodyJson.containsKey ('message' )
123+ ? bodyJson['message' ]!
124+ : utf8.decode (r.bodyBytes);
124125 throw DataConnectError (
125126 r.statusCode == 401
126127 ? DataConnectErrorCode .unauthorized
Original file line number Diff line number Diff line change @@ -274,6 +274,44 @@ void main() {
274274 ).called (1 );
275275 });
276276
277+ test (
278+ 'regression #17290 - invokeOperation should correctly decode UTF-8 response with international characters' ,
279+ () async {
280+ // Simulate a server response with Korean characters, where the
281+ // Content-Type header does NOT include charset=utf-8 (which is
282+ // what the Firebase emulator sends). Without explicit UTF-8
283+ // decoding, the http package defaults to latin1, corrupting
284+ // multi-byte characters.
285+ const koreanJson =
286+ '{"data": {"name": "\u d55c\u ad6d\u c5b4 \u d14c\u c2a4\u d2b8"}}' ;
287+ final mockResponse = http.Response .bytes (
288+ utf8.encode (koreanJson),
289+ 200 ,
290+ headers: {'content-type' : 'application/json' },
291+ );
292+ when (
293+ mockHttpClient.post (
294+ any,
295+ headers: anyNamed ('headers' ),
296+ body: anyNamed ('body' ),
297+ ),
298+ ).thenAnswer ((_) async => mockResponse);
299+
300+ final deserializer = (String data) => 'Deserialized Data' ;
301+
302+ final result = await transport.invokeOperation (
303+ 'testQuery' ,
304+ 'executeQuery' ,
305+ deserializer,
306+ null ,
307+ null ,
308+ null ,
309+ );
310+
311+ expect (result.data['data' ]['name' ],
312+ equals ('\u d55c\u ad6d\u c5b4 \u d14c\u c2a4\u d2b8' ));
313+ });
314+
277315 test (
278316 'invokeOperation should handle missing auth and appCheck tokens gracefully' ,
279317 () async {
You can’t perform that action at this time.
0 commit comments