如何解决:在transaction.update中,“方法'cast'在null上被调用”

时间:2019-04-01 21:46:28

标签: flutter google-cloud-firestore

尝试在Firestore集合上执行事务更新时出现NoSuchMethodError。

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上打印之前:<​​/ p>

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#10https://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 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,看起来像个错误。这导致异步功能出现问题,事务总是回调该异常

编辑: 我试图降级到0.9.6,没有问题。

答案 1 :(得分:0)

我在Cannot add PPA: 'ppa:travis-ci/sqlite3'. Please check that the PPA name or format is correct. 上遇到了同样的问题

升级到0.9.7对我来说是固定的,而降级到0.9.11无效。