I am trying to access userModel.uid
from UserProvider
inside the ItemProvider
so it can load _savedItems
.
However, when I call loadUserSavedItems()
, _userId
is null.
Here is my 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(),
),
),
);
}
UserProvider.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();
}
}
Can someone help me, I am not quite sure what I am missing, can't userModel
object/properties in ItemProvider.dart
when implemented as ChangeNotifierProxyProvider
.
I finally found a way around, maybe not the best but it worked.
Inside
ItemProvider
createdupdates()
to receive theuserId
fromAnd then made the changes in
main.dart
to pass theuserId
fromChangeNotifierProxyProvider
.Happy to hear what others have done as well.