Flutter Firestore NoSuchMethodError

时间:2018-07-30 02:34:28

标签: google-cloud-firestore flutter

我正在使用Flutter开发应用程序,并尝试通过使用类似这样的streambuilder方法从firestore中获取数据。

body: new StreamBuilder<DocumentSnapshot>(
    stream: Firestore.instance.collection('user').document(uid).collection('userInfo').document(uid).snapshots(),
    builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
      if (snapshot.connectionState == ConnectionState.waiting) return new Center(child: new CircularProgressIndicator());
      if (snapshot.hasData) {
        return new Center(
        child: ListView(
          shrinkWrap: true,
          padding: EdgeInsets.only(left: 24.0, right: 24.0),
          children: <Widget>[
            new Column(
              children: <Widget>[
                new CircleAvatar(
                  backgroundColor: Colors.transparent,
                  radius: 48.0,
                  child: Image.asset('assets/logo.png'),
                ),
                new Padding(padding: const EdgeInsets.only(bottom: 20.0)),
                new Text(snapshot.data['name'], 
                style: new TextStyle(fontSize: 28.0)),
                new Padding(padding: const EdgeInsets.only(bottom: 35.0)),
              ],
            ),
            new Column(
              children: <Widget>[
                new Row(
                  children: <Widget>[
                    new Column(
                      children: <Widget>[
                        new Icon(
                          Icons.accessibility,
                          size: 18.0,
                        ),
                        new Text('Age',
                            style: new TextStyle(
                                fontSize: 12.0, color: Colors.blue)),
                      ],
                    ),
                    new Padding(
                        padding: const EdgeInsets.only(right: 16.0)),
                    new Text(snapshot.data['age'].toString(), style: new TextStyle(fontSize: 25.0)),
                  ],
                ),
                new Padding(padding: const EdgeInsets.only(top: 3.0)),
                new Divider(color: Colors.grey, height: 1.0),
                new Padding(padding: const EdgeInsets.only(bottom: 25.0)),
                new Row(
                  children: <Widget>[
                    new Column(
                      children: <Widget>[
                        new Icon(
                          Icons.place,
                          size: 18.0,
                        ),
                        new Text('State',
                            style: new TextStyle(
                                fontSize: 11.0, color: Colors.blue)),
                      ],
                    ),
                    new Padding(
                        padding: const EdgeInsets.only(right: 16.0)),
                    new Text(snapshot.data['state'], style: new TextStyle(fontSize: 25.0)),
                  ],
                ),
                new Padding(padding: const EdgeInsets.only(top: 3.0)),
                new Divider(color: Colors.grey, height: 1.0),
                new Padding(padding: const EdgeInsets.only(bottom: 25.0)),
                new Row(
                  children: <Widget>[
                    new Column(
                      children: <Widget>[
                        new Icon(
                          Icons.audiotrack,
                          size: 18.0,
                        ),
                        new Text('Hobby',
                            style: new TextStyle( fontSize: 11.0, color: Colors.blue)),
                      ],
                    ),
                    new Padding(
                        padding: const EdgeInsets.only(right: 16.0)),
                    new Text(snapshot.data['hobby'], style: new TextStyle(fontSize: 26.0)),
                  ],
                ),
                new Padding(padding: const EdgeInsets.only(top: 3.0)),
                new Divider(color: Colors.grey, height: 1.0),
              ],
            ),
            new SizedBox(height: 45.0),
            new RaisedButton(
              child: new Text('New Request',
                  style:
                      new TextStyle(color: Colors.white, fontSize: 20.0)),
              color: Colors.blueAccent,
              splashColor: Colors.blueGrey,
              onPressed: () {
                _toNewRequest();
              },
            ),
          ],
        ),
      );
    } else {
        return new Center(
          child: new Text('You havent set profile'),
        );
      }
    },
  ),

但错误如此说明

  

flutter:引发以下NoSuchMethodError构建       StreamBuilder(脏,状态:颤动:        _StreamBuilderBaseState>#f91a2)方法“ []”为   调用为null。接收方:null尝试调用:[]   (“名称”)

但是如果我刷新(也许重新启动)该应用程序,请单击绿色箭头,

enter image description here

然后正确显示数据。 为什么在应用启动时这不起作用? 预先谢谢你!

1 个答案:

答案 0 :(得分:1)

由于存在多个问题,因此正在使用示例代码进行回答。 可用作在Firestore中使用streamBuilder的参考。

Stream Builder示例:

    SingleChildScrollView(
      child: StreamBuilder(
        stream: getClientProfile().snapshots(),
        builder: (context, snapshots) {
          if (snapshots.connectionState == ConnectionState.active) {
            Client client = Client.from(snapshots.data);
            return Column(
              children: [
                HeaderDetails(client.productCategories, client.businessName,
                    client.coverPhoto, client.avatarPhoto),
                SizedBox(
                  height: 20.0,
                ),
                _displayInformationCard(
                    client.businessCategory, client.businessDescription),
                _locationInformationCard(client.address.getFullAddress()),
                _contactInformation(client),
              ],
            );
          } else if (snapshots.connectionState == ConnectionState.waiting) {
            return Container(child: Center(child: CircularProgressIndicator()));
          } else {
            return Container(
              child: Column(
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Icon(Icons.warning),
                  ),
                  Text('Error in loadind data')
                ],
              ),
            );
          }
        },
      ),
    ); 

firestore调用示例:

    DocumentReference getClientProfile() {
        return _fireStore.collection(SELLERS_COLLECTION).document(docId);
    } 

和模型类,以dart构造文档:

    import 'package:cloud_firestore/cloud_firestore.dart';

class Client {
  final DocumentReference documentReference;
  String sellerId;
  String businessName, businessDescription, businessCategory;
  List productCategories;
  String coverPhoto, avatarPhoto;
  Representative representative;
  Address address;

  Client.data(this.documentReference,
      [this.sellerId,
      this.businessName,
      this.businessDescription,
      this.businessCategory,
      this.productCategories,
      this.coverPhoto,
      this.avatarPhoto,
      this.representative,
      this.address]) {
    this.sellerId ??= '';
    this.businessName ??= '';
    this.businessDescription ??= '';
    this.businessCategory ??= '';
    this.productCategories ??= [];
    this.coverPhoto ??= '';
    this.avatarPhoto ??=
        '';
  }

  factory Client.from(DocumentSnapshot document) => Client.data(
        document != null ? document.reference : null,
        document.data['sellerId'],
        document.data['businessName'],
        document.data['businessDescription'],
        document.data['businessCategory'],
        document.data['productCategories'],
        document.data['coverPhoto'],
        document.data['avatarPhoto'],
        Representative.from(document.data['representative']),
        Address.from(document.data['pickupAddress']),
      );

  Map<String, dynamic> toMap() {
    return {
      'sellerId': sellerId,
      'businessName': businessName,
      'businessDescription': businessDescription,
      'businessCategory': businessCategory,
      'productCategories': productCategories,
      'coverPhoto': coverPhoto,
      'avatarPhoto': avatarPhoto,
      'representative': representative.toMap(),
      'pickupAddress': address.toMap(),
    };
  }


}

class Address {
  String building;
  String street;
  String location;
  double lat;
  double lng;

  Address.data(this.building, this.street, this.location, this.lat, this.lng) {
    this.building ??= '';
    this.street ??= '';
    this.location ??= '';
    this.lat ??= 0.0;
    this.lng ??= 0.0;
  }

  factory Address.from(address) => Address.data(address['building'],
      address['street'], address['location'], address['lat'], address['lng']);

  getFullAddress() {
    return building + ', ' + street + '\n' + location;
  }

  Map<String, dynamic> toMap() {
    return {
      'building': building,
      'street': street,
      'location': location,
      'lat': lat,
      'lng': lng,
    };
  }
}

class Representative {
  String representativeName;
  String contactNumber;
  String email;

  Representative.data(this.representativeName, this.contactNumber, this.email) {
    this.representativeName ??= '';
    this.contactNumber ??= '';
    this.email ??= '';
  }

  factory Representative.from(representative) => Representative.data(
      representative['representativeName'],
      representative['contactNumber'],
      representative['email']);

  Map<String, dynamic> toMap() {
    return {
      'representativeName': representativeName,
      'contactNumber': contactNumber,
      'email': email,
    };
  }
}

该代码是使用this作为参考构建的。