首页 > 解决方案 > 参数类型'流' 不能分配给参数类型 'Stream>?

问题描述

我是 Flutter 的初学者,正在创建一个实时聊天应用程序。

发生错误的stream: usersStream,行说"The argument type 'Stream<dynamic>' can't be assigned to the parameter type 'Stream<QuerySnapshot<Object?>>?'."

Widget searchUsersList() {
    return StreamBuilder<QuerySnapshot>(
      stream: usersStream,
      builder: (context, snapshot) {
        return snapshot.hasData
            ? ListView.builder(
                shrinkWrap: true,
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (context, index) {
                  DocumentSnapshot ds = snapshot.data!.docs[index];
                  return Image.network(ds["imgUrl"]);
                },
              )
            : Center(
                child: CircularProgressIndicator(),
              );
      },
    );
  }

我正在使用 VScode 进行开发,下面是错误照片和完整代码

VScode 截图

完全错误说

lib/views/home.dart:34:15:错误:参数类型“Stream”不能分配给参数类型“Stream<QuerySnapshot<Object?>>?”。

完整代码 <home.dart>

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:messenger_clone/services/auth.dart';
import 'package:messenger_clone/services/database.dart';
import 'package:messenger_clone/views/signin.dart';
import 'package:flutter/src/material/icons.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

final databaseReference = FirebaseFirestore.instance;

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  bool isSearching = false;
  late Stream usersStream;

  TextEditingController searchUserNameEdittingController =
      TextEditingController();

  onSearchBtnClick() async {
    isSearching = true;
    setState(() {});
    usersStream = await DatabaseMethods()
        .getUserByUserName(searchUserNameEdittingController.text);
  }

  Widget searchUsersList() {
    return StreamBuilder<QuerySnapshot>(
      stream: usersStream,
      builder: (context, snapshot) {
        return snapshot.hasData
            ? ListView.builder(
                shrinkWrap: true,
                itemCount: snapshot.data!.docs.length,
                itemBuilder: (context, index) {
                  DocumentSnapshot ds = snapshot.data!.docs[index];
                  return Image.network(ds["imgUrl"]);
                },
              )
            : Center(
                child: CircularProgressIndicator(),
              );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("messenger clone"),
        actions: [
          InkWell(
            onTap: () {
              AuthMethods().signOut().then((s) {
                Navigator.pushReplacement(
                    context, MaterialPageRoute(builder: (context) => SignIn()));
              });
            },
            child: Container(
                padding: EdgeInsets.symmetric(horizontal: 16),
                child: Icon(Icons.exit_to_app)),
          )
        ],
      ),
      body: Container(
        margin: EdgeInsets.symmetric(horizontal: 20),
        child: Column(
          children: [
            Row(
              children: [
                isSearching
                    ? GestureDetector(
                        onTap: () {
                          isSearching = false;
                          searchUserNameEdittingController.text = "";
                          setState(() {});
                        },
                        child: Padding(
                            padding: EdgeInsets.only(right: 12),
                            child: Icon(Icons.arrow_back)),
                      )
                    : Container(),
                Expanded(
                  child: Container(
                    margin: EdgeInsets.symmetric(horizontal: 16),
                    padding: EdgeInsets.symmetric(horizontal: 16),
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: Colors.grey,
                            width: 1,
                            style: BorderStyle.solid),
                        borderRadius: BorderRadius.circular(24)),
                    child: Column(children: [
                      Row(
                        children: [
                          Expanded(
                              child: TextField(
                            controller: searchUserNameEdittingController,
                            decoration: InputDecoration(
                                border: InputBorder.none, hintText: "username"),
                          )),
                          GestureDetector(
                              onTap: () {
                                if (searchUserNameEdittingController.text !=
                                    "") {
                                  onSearchBtnClick();
                                }
                              },
                              child: Icon(Icons.search))
                        ],
                      ),
                    ]),
                  ),
                )
              ],
            ),
            searchUsersList()
          ],
        ),
      ),
    );
  }
}

====为了安全起见,我在这里添加了 pubspec.yaml===

name: messenger_clone
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

version: 1.0.0+1

environment:
  sdk: ">=2.12.0 <3.0.0"


dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  firebase_auth: ^3.1.4
  firebase_core: ^1.8.0
  google_sign_in: ^5.2.1
  shared_preferences: ^2.0.8
  random_string: ^2.3.1
  cloud_firestore: ^2.5.4

dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^1.0.0


flutter:


  uses-material-design: true

=====database.dart=====

import 'package:cloud_firestore/cloud_firestore.dart';

class DatabaseMethods {
  Future addUserInfoToDB(
      String userId, Map<String, dynamic> userInfoMap) async {
    return FirebaseFirestore.instance
        .collection("users")
        .doc(userId)
        .set(userInfoMap);
  }

  Future<Stream<QuerySnapshot>> getUserByUserName(String username) async {
    return FirebaseFirestore.instance
        .collection("users")
        .where("username", isEqualTo: username)
        .snapshots();
  }
}

=====我试过的======

<QuerySnapshot>・从小部件中删除

然后又出现了一个错误...

The getter 'docs' isn't defined for the type 'Object'.

itemCount: snapshot.data!.docs.length,itemBuilder: (context, index) { DocumentSnapshot ds = snapshot.data!.docs[index]; return Image.network(ds["imgUrl"]); },

正如我研究的那样,这也是一个火力问题,但我不确定哪个更好解决。

标签: firebaseflutterdart

解决方案


请在问题中添加DatabaseMethods().getUserByUserName()代码和详细信息。

您应该将快照传递给流构建器,检查以下示例:

  Stream<QuerySnapshot> getUsersStream() {
    return firestore.collection('user').snapshots();
  }

因此,如果您没有在DatabaseMethods().getUserByUserName()方法中返回快照,则可以usersStream.snapshots()使用userStream.


推荐阅读