Как исправить: «Метод cast был вызван на нуль» во время транзакции. - PullRequest
1 голос
/ 02 апреля 2019

Я получаю NoSuchMethodError при попытке выполнить обновление транзакции в моей коллекции Firestore.

Receiver: null
Tried calling: cast<String, dynamic>()
#0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
#1      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:331:19)
<asynchronous suspension>
#2      Firestore.runTransaction (file:///Users/wready/dev_tools/flutter/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.9.7+2/lib/src/firestore.dart:114:10)
<asynchronous suspension>
#3      _HomePageState._buildListItem.<anonymous closure> (package:maas_app/pages/home_page.dart:204:43)
#4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:513:14)
#5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:568:30)
#6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:120:24)
#7      TapGestureRecognizer._checkUp (package:flutter/src/gestures/t<…>

На самом деле он отлично обновляется на бэкенде и правильно отображается на моем симуляторе. Но я явно что-то здесь упускаю. Я не уверен, почему он получает эту ошибку, так как все операторы печати, которые я пробовал, не показывают нулевые объекты / ссылки.

Любая помощь очень ценится !!!

Перед печатью onTap:

flutter: Todo{subject: make flutter awesome, completed: false, userId: test@test.com, reference: Instance of 'DocumentReference'}

После печати onTap:

flutter: Todo{subject: make flutter awesome, completed: true, userId: test@test.com, reference: Instance of 'DocumentReference'}

Я пробовал разные варианты транзакции. Обновление, которое я видел в https://codelabs.developers.google.com/codelabs/flutter-firebase/index.html#10 и https://medium.com/flutter-community/simple-recipes-app-made-in-flutter-firestore-f386722102da

Оба корректно выполняют обновление в Firestore и UI, но выдают одно и то же исключение.

В разделе onTap происходит сбой:

  Widget _buildListItem(BuildContext context, DocumentSnapshot data) {
    final todo = Todo.fromSnapshot(data);

    print(todo);

    return Padding(
      key: ValueKey(todo.toString()),
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.grey),
          borderRadius: BorderRadius.circular(5.0),
        ),
        child: ListTile(
          title: Text(todo.subject),
          trailing: Text(todo.completed.toString()),
          onTap: () => Firestore.instance.runTransaction((Transaction transaction) async {
            final DocumentSnapshot freshSnapshot = await transaction.get(todo.reference);
            final Todo fresh = Todo.fromSnapshot(freshSnapshot);

            await transaction.update(todo.reference, {'completed': !fresh.completed});
          }),
        ),
      ),
    );
  }

Моя модель Todo:

import 'package:cloud_firestore/cloud_firestore.dart';

class Todo {
  final String subject;
  final bool completed;
  final String userId;
  final DocumentReference reference;

  Todo.fromMap(Map<String, dynamic> map, {this.reference})
      : assert(map['userId'] != null),
        assert(map['subject'] != null),
        assert(map['completed'] != null),
        userId = map['userId'],
        subject = map['subject'],
        completed = map['completed'];

  Todo.fromSnapshot(DocumentSnapshot snapshot)
      : this.fromMap(snapshot.data, reference: snapshot.reference);

  @override
  String toString() {
    return 'Todo{subject: $subject, completed: $completed, userId: $userId, reference: $reference}';
  }

}

ОБНОВЛЕНИЕ: Пробное обновление даже без использования моделей с заходом на посадку с https://www.youtube.com/watch?v=DqJ_KjFzL9I. По-прежнему получаю ту же ошибку: (

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class TodoListWidget extends StatelessWidget {

  TodoListWidget({this.firestore});

  final Firestore firestore;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: firestore.collection('todo').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (!snapshot.hasData) return const Text('Loading...');
        final int messageCount = snapshot.data.documents.length;
        return ListView.builder(
          itemCount: messageCount,
          itemBuilder: (_, int index) {
            final DocumentSnapshot document = snapshot.data.documents[index];
            return ListTile(
              title: Text(document['subject'] ?? '<No subject retrieved>'),
              trailing: Text(document['completed']?.toString() ?? '<No completed retrieved>'),
              onTap: () => Firestore.instance.runTransaction((Transaction transaction) async {
                final DocumentSnapshot freshSnapshot = await transaction.get(document.reference);

                await transaction.update(freshSnapshot.reference, {
                  'completed': !freshSnapshot.data['completed'],});
              }),

            );
          },
        );
      },
    );
  }
}

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

У меня та же проблема, похоже на ошибку.Это вызывает проблему с асинхронными функциями, транзакции всегда вызывают обратный вызов этого исключения

РЕДАКТИРОВАТЬ: Я пытался понизить до 0.9.6, и это не проблема.

0 голосов
/ 04 апреля 2019

Я столкнулся с той же проблемой на 0.9.7

Обновление до 0.9.11 исправило это для меня, в то время как понижение до 0.9.6 не работало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...