Matt Takao
Matt Takao

Reputation: 2996

flutter & firebase: writing successfully with error?

I have some seemingly very strange behavior. I've been following multiple tutorials on integrating firebase into my flutter app.

I'm trying to do something very simple. When the user presses a button, a "session" document is created.

I have this index.js:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.addSession = functions.https.onCall((data, context) => {
    const sessions = admin.firestore().collection('sessions');
    return sessions.add({
        game: data['game'],
        rules: data['rules'],
        password: data['password'],
        roomCode: data['roomCode'],
        playerIds: data['playerIds']
    });
});

When invoked in Flutter, the data is successfully written to the database (I can see it in the console), but I also always get this error: [VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: PlatformException(functionsError, Firebase function failed with exception., {message: INTERNAL, code: INTERNAL})

When I check the Firebase logs, I see this: enter image description here

Flutter invocation:

final HttpsCallable callable =
        CloudFunctions.instance.getHttpsCallable(functionName: 'addSession');
    await callable.call(<String, dynamic>{
      'game': game,
      'rules': 'default',
      'password': password,
      'roomCode': _roomCode,
      'playerIds': [123456],
    });

Very confused about this, nothing about maximum stack call size exceeded results seem to be relevant. This is very simple code!

Also wondering if this has anything to with reading issues I am having, which I will ask in a separate post.

Upvotes: 0

Views: 60

Answers (1)

Doug Stevenson
Doug Stevenson

Reputation: 317487

The problem is what you're returning from the function. Callable functions will generate a response to the client based on what the code returns. That response will be serialized to JSON. Your code returns a promise that resolves with a DocumentReference, and that DocumentReference doesn't serialize very well because it contains circular references.

What you should do instead is return something explicit and simple to the client. For example:

exports.addSession = functions.https.onCall(async (data, context) => {
    const sessions = admin.firestore().collection('sessions');
    await sessions.add({
        game: data['game'],
        rules: data['rules'],
        password: data['password'],
        roomCode: data['roomCode'],
        playerIds: data['playerIds']
    });
    return { result: "OK" }
});

You can return whatever you find more helpful, of course. Note that I'm using async/await synctax in JavaScript to make it easier. Promises work like Futures in dart.

Upvotes: 2

Related Questions