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
created updates()
to receive the userId
from
void updates(String userId, Status status) {
this._userId = userId;
}
And then made the changes in main.dart
to pass the userId
from 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(),
),
),
);
}
Happy to hear what others have done as well.