【问题标题】:Flutter Firestore _MapStream<DocumentSnapshotPlatform, DocumentSnapshot> is not a subtype of Stream<QuerySnapshot>Flutter Firestore _MapStream<DocumentSnapshotPlatform, DocumentSnapshot> 不是 Stream<QuerySnapshot> 的子类型
【发布时间】:2021-03-09 20:49:12
【问题描述】:

经过数小时的挣扎和浏览,我需要您的帮助。

我正在执行一个带有 Firestore 的颤振项目。我正在使用 Riverpod 进行 mvvm 架构。

我的 Firestore 服务有这个代码:

CollectionReference getCollection(String collection) =>
      _firestore.collection(collection);

  getCurrentCustomer() {
    String uid = _auth.currentUser.uid;
    print('current customer id is : $uid');
    var customerStream = getCollection('customer')
        .doc(uid)
        .snapshots(includeMetadataChanges: true);
    print('customerStream is a $customerStream');
    return customerStream;
  }

我通过这个提供商访问这个 FirestoreService :

final firestoreProvider = Provider<FirestoreService>((ref) {
  return FirestoreService(
    ref.read(authentificationServiceProvider),
  );
});

在我的 CustomerProfileViewModel 上我得到了这个:

final customerProfileViewModelProvider =
    ChangeNotifierProvider<CustomerProfileViewModel>((ref) {
  return CustomerProfileViewModel(
    ref.read(authentificationServiceProvider),
    ref.read(navigationServiceProvider),
    ref.read(firestoreProvider),
  );
});

class CustomerProfileViewModel extends ChangeNotifier {
  final AuthentificationService _auth;
  final NavigationService _navigationService;
  final FirestoreService _firestore;

  CustomerProfileViewModel(
      this._auth, this._navigationService, this._firestore);


  getCurrentCustomerInfo() {
    Stream customerStream = _firestore.getCurrentCustomer();
    print('customer Stream sur le model est $customerStream');
    return customerStream;
  }

  updateCurrentUserInfo({String dataField, dataValue}) {
    _firestore.updateCurrentCustomerInfo(dataField, dataValue);
    notifyListeners();
  }
}

最后,在作为 ConsumerWidget 的 CustomerProfileView 中,我这样称呼我的模型:

var model = watch(customerProfileViewModelProvider);
var stream = model.getCurrentCustomerInfo();

我的 StreamBuilder 设置是这样的

StreamBuilder(
                stream: stream,
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> snapshot
    )

然后我得到这个错误:

I/flutter ( 2609): current customer id is : 9tZTfddurwQRsSuGnH7pkPvmvvF2
I/flutter ( 2609): customerStream is a Instance of '_MapStream<DocumentSnapshotPlatform, DocumentSnapshot>'
I/flutter ( 2609): customer Stream sur le model est Instance of '_MapStream<DocumentSnapshotPlatform, DocumentSnapshot>'
I/flutter ( 2609): stream view est Instance of '_MapStream<DocumentSnapshotPlatform, DocumentSnapshot>'

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following _TypeError was thrown building CustomerProfileView(dirty, dependencies: [UncontrolledProviderScope], state: _ConsumerState#b4319):
type '_MapStream<DocumentSnapshotPlatform, DocumentSnapshot>' is not a subtype of type 'Stream<QuerySnapshot>'

The relevant error-causing widget was: 
  CustomerProfileView file:///Users/Alex/AndroidStudioProjects/clickncollect/lib/ui/views/home/home_viewmodel.dart:35:16
When the exception was thrown, this was the stack: 
#0      CustomerProfileView.build (package:clickncollect_app/ui/views/customer/customer_profile/customer_profile_view.dart:40:25)
#1      _ConsumerState.build (package:flutter_riverpod/src/consumer.dart:300:35)
#2      StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
#3      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
#4      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4800:11)
...
════════════════════════════════════════════════════════════════════════════════════════════════

它使用 Future 进行所有相同的工作,使用 collection('customers').doc(uid).get() 查询并使用 FutureBuilder 构建它。

请帮助我,我从未见过这种 MapStream 类型,互联网也没有(经过数小时的搜索)。

感谢阅读!

【问题讨论】:

  • getCurrentCustomer 函数返回一个 _MapStream&lt;DocumentSnapshotPlatform, DocumentSnapshot&gt; 对象,StreamBuilder : 流需要一个 Stream&lt;QuerySnapshot&gt; 对象。你可以找到here一个例子stream: Firestore.instance.collection('Videos').snapshots()
  • 感谢您的回复。我完全意识到这一点,这就是为什么我的函数 getCurrentCustomer 返回 _MapStream 而不是 Stream 的原因。它应该返回最后一种类型。

标签: flutter mvvm google-cloud-firestore riverpod


【解决方案1】:

似乎不可能从 DocumentReference 请求一个流。 所以我用 where 条件过滤了我的 CollectionReference 快照。 我先试过了:

getCurrentCustomerInfo() {
    var uid = _auth.currentUser.uid;
  
    Stream customerStream = _firestore
        .getCollection('customers')
        .where('id', isEqualTo: uid)
        .snapshots();
    print('customer Stream on the model is ${customerStream}');
    return customerStream;
  }

但它没有用。 然后我发现 'id' 在 where 条件是问题所在,我发现了这个:

getCurrentCustomerInfo() {
    var uid = _auth.currentUser.uid;
    
    Stream customerStream = _firestore
        .getCollection('customers')
        .where(FieldPath.documentId, isEqualTo: uid)
        .snapshots();
    print('customer Stream on the model is ${customerStream}');
    return customerStream;
  }

然后在视图上你必须用这个来获取第一个元素

var customer = snapshot.data.docs.first.data();

然后您从流中获取快照中的数据。所以它会更新!

【讨论】:

  • 嗨,Alexandre Savinien,找到解决方案做得很好!你能accept your own answer吗?它将使其更加明显,并在您找到解决方案时帮助遇到相同问题的人。谢谢!
  • 您好 Jose,很遗憾,但可以理解的是,我无法为自己的答案投票。
【解决方案2】:
StreamBuilder(
    stream: stream,
    builder: (BuildContext context,
        AsyncSnapshot<DocumentSnapshot> snapshot //Your stream is of type <DocumentSnapshot> not <QuerySnapshot>
    // change it like this
)

为什么?在函数getCurrentCostumer() 你返回

var customerStream = getCollection('customer').doc(uid)
  .snapshots(includeMetadataChanges: true);

如果您将 var 更改为 Stream&lt;QuerySnapshot&gt;,编辑器会警告您这不是流返回的类型,QuerySnapshot 是扩展 DocumentSnapshot 的类,而不是相反,当您使用像 @987654326 这样的查询时使用@、limitAtendsAt 等,所以不是 Dart 误解了类型,而是您将其转换为不同的类型

_MapStream&lt;DocumentSnapshotPlatfom, DocumentSnapshot&gt; 是什么,而不是你问的 Stream?

快照使用函数mapStream.map()将每个元素转换为一个新的流事件,实现使用this _MapStream(this, convert)所以它将事件T转换为S,在这种情况下DocumentSnapshotPlatfomDocumentSnapshot,这样你现在应该返回的流类型为 DocumentSnapshot

【讨论】:

  • 您好,感谢您的回答!我从使用 get() 和 future 的简单查询开始,DocumentSnapshot 类型来自于它。然后我想尝试使用流并忘记将其更改为 QuerySnapshot。既然你指出了它,我对我花在它上面的时间感到有点不好......顺便说一句,非常感谢你对 _MapStream 的解释,我找不到任何相关信息。
猜你喜欢
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
相关资源
最近更新 更多