1

我正在尝试userModel.uidUserProvider内部访问,ItemProvider以便它可以加载_savedItems

但是,当我调用时loadUserSavedItems()_userId为空。

这是我的 main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';


void main() {
  Provider.debugCheckInvalidValueType = null;
  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<UserProvider>(
            create: (_) => UserProvider.initialize()),
        ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
          create: (_) => ItemProvider(),
          update: (_, userProvider, itemProvider) => itemProvider,
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.white,
          primaryTextTheme: TextTheme(
            headline6: TextStyle(color: Colors.black),
          ),
        ),
        home: Home(),
      ),
    ),
  );
}

用户提供者.dart


import 'models/user.dart';
import 'services/user.dart';

enum Status { Uninitialized, Authenticated, Authenticating, Unauthenticated }

class UserProvider extends ChangeNotifier {
  FirebaseAuth _auth;
  FirebaseUser _user;
  Status _status = Status.Uninitialized;
  Firestore _firestore = Firestore.instance;
  UserServices _userServicse = UserServices();
  UserModel _userModel;

//  getter
  UserModel get userModel => _userModel;
  Status get status => _status;
  FirebaseUser get user => _user;

  UserProvider.initialize() : _auth = FirebaseAuth.instance {
    _auth.onAuthStateChanged.listen(_onStateChanged);
    notifyListeners();
  }

  Future<void> _onStateChanged(FirebaseUser firebaseUser) async {
    if (firebaseUser == null) {
      _status = Status.Unauthenticated;
    } else {
      _user = firebaseUser;
      _status = Status.Authenticated;
      _userModel = await _userServicse.getUserById(user.uid);
    }
    notifyListeners();
  }

  Future<bool> signIn() async {
    bool retVal = false;
    try {
      _status = Status.Authenticating;
      notifyListeners();
      AuthResult _authResult = await _auth.signInWithEmailAndPassword(
          email: email.text.trim(), password: password.text.trim());
      if (_authResult.user != null) {
        retVal = true;
      }
    } catch (e) {
      _status = Status.Unauthenticated;
      notifyListeners();
      print(e.toString());
    }
    return retVal;
  }
}

ItemProvider.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
import 'models/item.dart';
import 'providers/user.dart';
import 'services/item.dart';

class ItemProvider extends ChangeNotifier {
  ItemProvider({UserProvider userProvider}) : _userProvider = userProvider;

  UserProvider _userProvider;

  final databaseReference = Firestore.instance;
  ItemServices _itemServices = ItemServices();
  List<Item> _items = [];
  List<Item> _savedItems = [];
  String _userId;

  //  getter
  List<Item> get items => _items;
  List<Item> get savedItems => _savedItems;
  String get userId => _userId;
  UserProvider get userProvider => _userProvider;

  //get the items to load when the app is initiated
  ItemProvider.initialize() {
    loadAllActiveItems();
    if (_userProvider.status == Status.Authenticated) {
      loadUserSavedItems();
    }
  }

  //get active items from DB
  loadAllActiveItems() async {
    _items = await _itemServices.getBatchOfActiveItems();
    notifyListeners();
  }

  //get user saved items from DB
  loadUserSavedItems() async {
    _userId = userProvider.userModel.uid;
    _savedItems = await _itemServices.getUserSavedItems(userId);
    notifyListeners();
  }
}

有人可以帮助我吗,我不太确定我错过了什么userModelItemProvider.dart当实现为ChangeNotifierProxyProvider.

4

1 回答 1

0

我终于找到了一种方法,也许不是最好的,但它确实有效。

内部ItemProvider创建updates()以接收userId来自

  void updates(String userId, Status status) {
    this._userId = userId;
  }

然后进行更改main.dart以传递userIdfrom ChangeNotifierProxyProvider

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'providers/user.dart';
import 'providers/item.dart';
import 'screens/home.dart';


void main() {
  Provider.debugCheckInvalidValueType = null;
  WidgetsFlutterBinding.ensureInitialized();

  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider<UserProvider>(
            create: (_) => UserProvider.initialize()),
        ChangeNotifierProxyProvider<UserProvider, ItemProvider>(
          create: (_) => ItemProvider(),
          update: (_, userProvider, itemProvider) => itemProvider
            ..updates(
                userProvider.user != null ? userProvider.user.uid : ''),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.white,
          primaryTextTheme: TextTheme(
            headline6: TextStyle(color: Colors.black),
          ),
        ),
        home: Home(),
      ),
    ),
  );
}


很高兴听到其他人也做了什么。

于 2020-12-10T10:19:52.557 回答