首页 > 解决方案 > 找不到正确的提供者在这个 xxxx 小部件上方

问题描述

我是 Flutter 的新手,目前想从 Firebase 获取数据并在主屏幕上显示它,但是它会出现这样的错误,我不清楚这是怎么回事?错误代码如下

发生这种情况是因为您使用了BuildContext不包括您选择的提供者的 。有几种常见的场景:

在我的主要有使用多个提供者

ChangeNotifierProxyProvider<Auth, UserProfileLogic>(
          update: (ctx, auth, previousProfile) => UserProfileLogic(
            auth.token,
            auth.userId,
            previousProfile == null ? [] : previousProfile.items,
          ),
          create: null,
        ), 

在 user_profile_item.dart 文件中尝试移动声明主屏幕中显示的内容。我在这里有一些选择,或者使用构造函数并将整个函数传递给主屏幕并在构建上下文中调用 Provider 但是它也失败了,所以我更改了在此类中声明提供程序的选项并调用此方法也无法正常工作

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

import '../providers/user_profile.dart';

class UserProfileItem extends StatelessWidget {
  // final String username;
  // final String age;
  // final String gender;
  // final String bio;

  // UserProfileItem(this.username, this.age, this.gender, this.bio);

  @override
  Widget build(BuildContext context) {
    final product = Provider.of<UserProfile>(context, listen: false);
    return Column(
      children: [
        Card(
          elevation: 6,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Column(
                children: [
                  Container(
                    height: MediaQuery.of(context).size.height * 0.25,
                    child: CircleAvatar(
                      backgroundImage: AssetImage(
                        "assets/images/Materials-25.png",
                      ),
                      radius: 70,
                      child: FittedBox(
                        fit: BoxFit.fitHeight,
                      ),
                    ),
                  ),
                ],
              ),
              Text(product.username),
              Text(product.username),
              Text(product.username),
              Text(product.username),
            ],
          ),
        ),
      ],
    );
  }
}

Home_Screen 显示,但是它也像上面一样出现错误,正如我提到的那样,我尝试了两种方式,但它也失败了

  Widget build(BuildContext context) {
    //final product = Provider.of<UserProfile>(context, listen: false);
    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        // "Navigator.push" returns a Future and "onPressed" accepts void
        //so cannot directly use "Navigator" but if using () =>
        //simply means that executing "Navigator..."
        onPressed: () =>
            Navigator.of(context).pushNamed(SocialProfileScreen.routeName),
      ),
      appBar: AppBar(
        title: Text("Meetups"),
      ),
      drawer: AppDrawer(),
      body: UserProfileItem(),
    );
  }

(Home_screen)我已经从 Firebase 获取数据了,有没有根据我的案例直接获取用户数据的快速解决方案?

  @override
  void didChangeDependencies() {
    if (_isInit) {
      setState(() {
        _isLoading = true;
      });
      Provider.of<UserProfileLogic>(context).fetchAndSetUserProfile().then((_) {
        setState(() {
          _isLoading = false;
        });
      });
    }
    _isInit = false;
    super.didChangeDependencies();
  }

这是我从数据库中获取的方式

Future<void> fetchAndSetUserProfile([bool filterByUser = false]) async {
    final filterString =
        filterByUser ? "orderBy='creatorId'&equalTo='$userId'" : '';

    var url = Uri.parse(
        "https://meetup-aed5f-default-rtdb.asia-southeast1.firebasedatabase.app/userprofile/$userId.json?auth=$authToken$filterString"); // this mean creatorId equal to userId
    try {
      final response = await http.get(url);
      final extractedData = json.decode(response.body) as Map<String, dynamic>;
      if (extractedData == null) {
        return;
      }
      final List<UserProfile> loadedProducts = [];
      extractedData.forEach((prodId, prodData) {
        loadedProducts.add(UserProfile(
          userprofileid: prodId,
          username: prodData['username'],
          age: prodData['age'],
          gender: prodData['gender'],
          bio: prodData['bio'],
        ));
      });
      _items = loadedProducts;
      notifyListeners();
    } catch (error) {
      throw (error);
    }
  }

标签: flutterflutter-layout

解决方案


您可能应该在 Provider 的创建字段中返回一个 UserProfileLogic 实例!

ChangeNotifierProxyProvider<Auth, UserProfileLogic>(
      update: (ctx, auth, previousProfile) => UserProfileLogic(
        auth.token,
        auth.userId,
        previousProfile == null ? [] : previousProfile.items,
      ),
      create: (ctx) => UserProfileLogic(null, null, []),
    ), 

推荐阅读