Skip to content

Commit cd19aac

Browse files
Move the filter from local storage to Firestore (#97)
* move filter from local storage to Firestore * reformat code * bump version * try to fix filter bugs * move filter from local storage to firebase - fix bugs * move filter from local storage to firebase - fix bugs * move filter from local storage to firebase - fix bugs * remove useless conditions * delete useless code and make setFilterNodes private method * reformat code * delete unused import * Fix popupmenu offset It popped lower than it should have, maybe something changed in the Flutter defaults * Fix filter acting odd on auth state changes * bump version Co-authored-by: Ioana Alexandru <ioanaa.alexandru98@gmail.com>
1 parent ba0dbd2 commit cd19aac

File tree

7 files changed

+64
-51
lines changed

7 files changed

+64
-51
lines changed

lib/authentication/service/auth_provider.dart

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import 'package:acs_upb_mobile/widgets/toast.dart';
99
import 'package:cloud_firestore/cloud_firestore.dart';
1010
import 'package:firebase_auth/firebase_auth.dart';
1111
import 'package:flutter/material.dart';
12-
import 'package:provider/provider.dart';
1312

1413
extension DatabaseUser on User {
1514
static User fromSnap(DocumentSnapshot snap) {
@@ -142,7 +141,7 @@ class AuthProvider with ChangeNotifier {
142141
}
143142

144143
String get uid {
145-
return _firebaseUser.uid;
144+
return _firebaseUser?.uid;
146145
}
147146

148147
String get email => _firebaseUser.email;
@@ -392,17 +391,21 @@ class AuthProvider with ChangeNotifier {
392391
_firebaseUser = await FirebaseAuth.instance.currentUser();
393392

394393
// Create document in 'users'
395-
final user = User(
394+
_currentUser = User(
396395
uid: res.user.uid,
397396
firstName: firstName,
398397
lastName: lastName,
399398
classes: classes,
400399
);
401400

402401
final DocumentReference ref =
403-
Firestore.instance.collection('users').document(user.uid);
404-
await ref.setData(user.toData());
402+
Firestore.instance.collection('users').document(_currentUser.uid);
403+
await ref.setData(_currentUser.toData());
405404

405+
// Try to set the default from the user data
406+
if (_currentUser.classes != null) {
407+
await ref.updateData({'filter_nodes': _currentUser.classes});
408+
}
406409
// Send verification e-mail
407410
await _firebaseUser.sendEmailVerification();
408411

@@ -445,16 +448,15 @@ class AuthProvider with ChangeNotifier {
445448

446449
final classes = info['class'];
447450

448-
final User user =
449-
await Provider.of<AuthProvider>(context, listen: false).currentUser
450-
..firstName = firstName
451-
..lastName = lastName
452-
..classes = classes;
451+
_currentUser
452+
..firstName = firstName
453+
..lastName = lastName
454+
..classes = classes;
453455

454456
await Firestore.instance
455457
.collection('users')
456-
.document(user.uid)
457-
.updateData(user.toData());
458+
.document(_currentUser.uid)
459+
.updateData(_currentUser.toData());
458460

459461
// Update display name
460462
final userUpdateInfo = UserUpdateInfo()

lib/main.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@ Future<void> main() async {
4646
ChangeNotifierProvider<PersonProvider>(create: (_) => PersonProvider()),
4747
ChangeNotifierProvider<QuestionProvider>(create: (_) => QuestionProvider()),
4848
ChangeNotifierProvider<NewsProvider>(create: (_) => NewsProvider()),
49-
ChangeNotifierProvider<FilterProvider>(
50-
create: (_) =>
51-
FilterProvider(global: true, authProvider: authProvider)),
49+
ChangeNotifierProxyProvider<AuthProvider, FilterProvider>(
50+
create: (_) => FilterProvider(global: true),
51+
update: (context, authProvider, filterProvider) {
52+
return filterProvider..updateAuth(authProvider);
53+
},
54+
),
5255
ChangeNotifierProxyProvider2<ClassProvider, FilterProvider,
5356
UniEventProvider>(
5457
create: (_) => UniEventProvider(

lib/pages/filter/service/filter_provider.dart

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,9 @@ class FilterProvider with ChangeNotifier {
2424
{this.global = false,
2525
bool filterEnabled,
2626
this.defaultDegree,
27-
this.defaultRelevance,
28-
AuthProvider authProvider})
27+
this.defaultRelevance})
2928
: _enabled = filterEnabled ?? PrefService.get('relevance_filter') ?? true,
30-
_relevantNodes = defaultRelevance,
31-
authProvider = authProvider ?? AuthProvider() {
29+
_relevantNodes = defaultRelevance {
3230
if (defaultRelevance != null && !defaultRelevance.contains('All')) {
3331
if (defaultDegree == null) {
3432
throw ArgumentError(
@@ -49,17 +47,33 @@ class FilterProvider with ChangeNotifier {
4947
List<String> _relevantNodes;
5048
final List<String> defaultRelevance;
5149

52-
final AuthProvider authProvider;
50+
AuthProvider _authProvider;
5351

54-
void resetFilter() {
55-
_relevanceFilter = null;
52+
void updateAuth(AuthProvider authProvider) {
53+
_authProvider = authProvider;
54+
clearCache();
55+
}
5656

57+
void clearCache() {
58+
_relevanceFilter = null;
5759
_relevantNodes = null;
60+
5861
if (global) {
59-
// Reset defaults
60-
PrefService.setStringList('relevant_nodes', null);
62+
// TODO(IoanaAlexandru): Remove this property
6163
PrefService.setBool('relevance_filter', true);
6264
}
65+
66+
notifyListeners();
67+
}
68+
69+
Future<void> _setFilterNodes(List<String> nodes) async {
70+
try {
71+
final DocumentReference doc =
72+
_db.collection('users').document(_authProvider.uid);
73+
await doc.updateData({'filter_nodes': nodes});
74+
} catch (e) {
75+
print(e);
76+
}
6377
}
6478

6579
void enableFilter() {
@@ -85,8 +99,7 @@ class FilterProvider with ChangeNotifier {
8599
void updateFilter(Filter filter) {
86100
_relevanceFilter = filter;
87101
if (global) {
88-
PrefService.setStringList(
89-
'relevant_nodes', _relevanceFilter.relevantNodes);
102+
_setFilterNodes(_relevanceFilter.relevantNodes);
90103
}
91104
notifyListeners();
92105
}
@@ -113,34 +126,31 @@ class FilterProvider with ChangeNotifier {
113126
levelNames.add(Map<String, String>.from(name));
114127
}
115128

116-
// Check if there is an existing setting already
117-
if (global) {
118-
_relevantNodes = PrefService.get('relevant_nodes') == null
119-
? null
120-
: List<String>.from(PrefService.get('relevant_nodes'));
121-
}
122-
123129
final root = data['root'];
124130
_relevanceFilter = Filter(
125131
localizedLevelNames: levelNames,
126132
root: FilterNodeExtension.fromMap(root, 'All'),
127133
);
128134

129-
if (_relevantNodes != null) {
130-
_relevantNodes ??= defaultRelevance;
131-
for (final node in _relevantNodes) {
135+
// Set the default relevance, if provided
136+
if (defaultRelevance != null) {
137+
for (final node in defaultRelevance) {
132138
_relevanceFilter.setRelevantUpToRoot(node, defaultDegree);
133139
}
134140
_relevantNodes = _relevanceFilter.relevantNodes;
135-
} else {
136-
// No previous setting or defaults => set the user's group
137-
if (authProvider.isAuthenticatedFromCache) {
138-
final user = await authProvider.currentUser;
139-
// Try to set the default from the user data
140-
if (user != null && user.classes != null) {
141-
_relevanceFilter.setRelevantNodes(user.classes);
142-
}
143-
}
141+
}
142+
143+
// Check if there is an existing setting already
144+
if (global &&
145+
_authProvider.isAuthenticatedFromCache &&
146+
!_authProvider.isAnonymous) {
147+
final DocumentReference docUsers =
148+
_db.collection('users').document(_authProvider.uid);
149+
final DocumentSnapshot snapUsers = await docUsers.get();
150+
151+
//Load filter_nodes from Firestore
152+
_relevantNodes = List<String>.from(snapUsers['filter_nodes']);
153+
_relevanceFilter.setRelevantNodes(_relevantNodes);
144154
}
145155

146156
return cachedFilter;

lib/pages/timetable/service/uni_event_provider.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ class UniEventProvider extends EventProvider<UniEventInstance>
269269
return events
270270
.where((event) =>
271271
event.relevance == null ||
272-
(event.degree == _filter.baseNode &&
272+
(_filter != null &&
273+
event.degree == _filter.baseNode &&
273274
event.relevance.any(_filter.relevantNodes.contains)))
274275
.map((e) => e.generateInstances(intersectingInterval: interval))
275276
.expand((e) => e);

lib/resources/utils.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import 'package:acs_upb_mobile/authentication/service/auth_provider.dart';
22
import 'package:acs_upb_mobile/generated/l10n.dart';
33
import 'package:acs_upb_mobile/navigation/routes.dart';
4-
import 'package:acs_upb_mobile/pages/filter/service/filter_provider.dart';
54
import 'package:acs_upb_mobile/widgets/toast.dart';
65
import 'package:flutter/material.dart';
76
import 'package:pedantic/pedantic.dart';
@@ -47,11 +46,9 @@ class Utils {
4746

4847
static Future<void> signOut(BuildContext context) async {
4948
final authProvider = Provider.of<AuthProvider>(context, listen: false);
50-
final filterProvider = Provider.of<FilterProvider>(context, listen: false);
5149
unawaited(Navigator.pushNamedAndRemoveUntil(
5250
context, Routes.login, (route) => false));
5351
unawaited(authProvider.signOut());
54-
filterProvider.resetFilter();
5552
}
5653

5754
static String wrapUrlWithCORS(String url) {

lib/widgets/scaffold.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class AppScaffold extends StatelessWidget {
7777
))
7878
.toList();
7979
},
80-
offset: const Offset(0, 100),
80+
offset: const Offset(0, 15),
8181
)
8282
: Tooltip(
8383
message: action?.tooltip ?? action?.text ?? '',

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ description: A mobile application for students at ACS UPB.
1313
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
1414
#
1515
# ACS UPB Mobile uses semantic versioning. You can read more in the CONTRIBUTING.md file.
16-
version: 1.2.3+2
16+
version: 1.2.4+1
1717

1818
environment:
1919
sdk: ">=2.7.0 <3.0.0"

0 commit comments

Comments
 (0)