1
1
import 'package:cloud_firestore/cloud_firestore.dart' ;
2
2
import 'package:firebase_auth/firebase_auth.dart' ;
3
3
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
4
+ import 'firebase_chat_core_config.dart' ;
4
5
import 'util.dart' ;
5
6
6
7
/// Provides access to Firebase chat data. Singleton, use
@@ -12,6 +13,13 @@ class FirebaseChatCore {
12
13
});
13
14
}
14
15
16
+ /// Config to set custom names for rooms and users collections. Also
17
+ /// see [FirebaseChatCoreConfig] .
18
+ FirebaseChatCoreConfig config = const FirebaseChatCoreConfig (
19
+ 'rooms' ,
20
+ 'users' ,
21
+ );
22
+
15
23
/// Current logged in user in Firebase. Does not update automatically.
16
24
/// Use [FirebaseAuth.authStateChanges] to listen to the state changes.
17
25
User ? firebaseUser = FirebaseAuth .instance.currentUser;
@@ -20,6 +28,12 @@ class FirebaseChatCore {
20
28
static final FirebaseChatCore instance =
21
29
FirebaseChatCore ._privateConstructor ();
22
30
31
+ /// Sets custom config to change default names for rooms
32
+ /// and users collcetions. Also see [FirebaseChatCoreConfig] .
33
+ void setConfig (FirebaseChatCoreConfig firebaseChatCoreConfig) {
34
+ config = firebaseChatCoreConfig;
35
+ }
36
+
23
37
/// Creates a chat group room with [users] . Creator is automatically
24
38
/// added to the group. [name] is required and will be used as
25
39
/// a group name. Add an optional [imageUrl] that will be a group avatar
@@ -32,10 +46,16 @@ class FirebaseChatCore {
32
46
}) async {
33
47
if (firebaseUser == null ) return Future .error ('User does not exist' );
34
48
35
- final currentUser = await fetchUser (firebaseUser! .uid);
49
+ final currentUser = await fetchUser (
50
+ firebaseUser! .uid,
51
+ config.usersCollectionName,
52
+ );
53
+
36
54
final roomUsers = [types.User .fromJson (currentUser)] + users;
37
55
38
- final room = await FirebaseFirestore .instance.collection ('rooms' ).add ({
56
+ final room = await FirebaseFirestore .instance
57
+ .collection (config.roomsCollectionName)
58
+ .add ({
39
59
'createdAt' : FieldValue .serverTimestamp (),
40
60
'imageUrl' : imageUrl,
41
61
'metadata' : metadata,
@@ -73,11 +93,12 @@ class FirebaseChatCore {
73
93
if (fu == null ) return Future .error ('User does not exist' );
74
94
75
95
final query = await FirebaseFirestore .instance
76
- .collection ('rooms' )
96
+ .collection (config.roomsCollectionName )
77
97
.where ('userIds' , arrayContains: fu.uid)
78
98
.get ();
79
99
80
- final rooms = await processRoomsQuery (fu, query);
100
+ final rooms =
101
+ await processRoomsQuery (fu, query, config.usersCollectionName);
81
102
82
103
try {
83
104
return rooms.firstWhere ((room) {
@@ -91,10 +112,16 @@ class FirebaseChatCore {
91
112
// Create a new room instead
92
113
}
93
114
94
- final currentUser = await fetchUser (fu.uid);
115
+ final currentUser = await fetchUser (
116
+ fu.uid,
117
+ config.usersCollectionName,
118
+ );
119
+
95
120
final users = [types.User .fromJson (currentUser), otherUser];
96
121
97
- final room = await FirebaseFirestore .instance.collection ('rooms' ).add ({
122
+ final room = await FirebaseFirestore .instance
123
+ .collection (config.roomsCollectionName)
124
+ .add ({
98
125
'createdAt' : FieldValue .serverTimestamp (),
99
126
'imageUrl' : null ,
100
127
'metadata' : metadata,
@@ -116,7 +143,10 @@ class FirebaseChatCore {
116
143
/// Creates [types.User] in Firebase to store name and avatar used on
117
144
/// rooms list
118
145
Future <void > createUserInFirestore (types.User user) async {
119
- await FirebaseFirestore .instance.collection ('users' ).doc (user.id).set ({
146
+ await FirebaseFirestore .instance
147
+ .collection (config.usersCollectionName)
148
+ .doc (user.id)
149
+ .set ({
120
150
'createdAt' : FieldValue .serverTimestamp (),
121
151
'firstName' : user.firstName,
122
152
'imageUrl' : user.imageUrl,
@@ -130,13 +160,16 @@ class FirebaseChatCore {
130
160
131
161
/// Removes [types.User] from `users` collection in Firebase
132
162
Future <void > deleteUserFromFirestore (String userId) async {
133
- await FirebaseFirestore .instance.collection ('users' ).doc (userId).delete ();
163
+ await FirebaseFirestore .instance
164
+ .collection (config.usersCollectionName)
165
+ .doc (userId)
166
+ .delete ();
134
167
}
135
168
136
169
/// Returns a stream of messages from Firebase for a given room
137
170
Stream <List <types.Message >> messages (types.Room room) {
138
171
return FirebaseFirestore .instance
139
- .collection ('rooms /${room .id }/messages' )
172
+ .collection ('${ config . roomsCollectionName } /${room .id }/messages' )
140
173
.orderBy ('createdAt' , descending: true )
141
174
.snapshots ()
142
175
.map (
@@ -169,10 +202,12 @@ class FirebaseChatCore {
169
202
if (fu == null ) return const Stream .empty ();
170
203
171
204
return FirebaseFirestore .instance
172
- .collection ('rooms' )
205
+ .collection (config.roomsCollectionName )
173
206
.doc (roomId)
174
207
.snapshots ()
175
- .asyncMap ((doc) => processRoomDocument (doc, fu));
208
+ .asyncMap (
209
+ (doc) => processRoomDocument (doc, fu, config.usersCollectionName),
210
+ );
176
211
}
177
212
178
213
/// Returns a stream of rooms from Firebase. Only rooms where current
@@ -192,16 +227,20 @@ class FirebaseChatCore {
192
227
193
228
final collection = orderByUpdatedAt
194
229
? FirebaseFirestore .instance
195
- .collection ('rooms' )
230
+ .collection (config.roomsCollectionName )
196
231
.where ('userIds' , arrayContains: fu.uid)
197
232
.orderBy ('updatedAt' , descending: true )
198
233
: FirebaseFirestore .instance
199
- .collection ('rooms' )
234
+ .collection (config.roomsCollectionName )
200
235
.where ('userIds' , arrayContains: fu.uid);
201
236
202
- return collection
203
- .snapshots ()
204
- .asyncMap ((query) => processRoomsQuery (fu, query));
237
+ return collection.snapshots ().asyncMap (
238
+ (query) => processRoomsQuery (
239
+ fu,
240
+ query,
241
+ config.usersCollectionName,
242
+ ),
243
+ );
205
244
}
206
245
207
246
/// Sends a message to the Firestore. Accepts any partial message and a
@@ -246,7 +285,7 @@ class FirebaseChatCore {
246
285
messageMap['updatedAt' ] = FieldValue .serverTimestamp ();
247
286
248
287
await FirebaseFirestore .instance
249
- .collection ('rooms /$roomId /messages' )
288
+ .collection ('${ config . roomsCollectionName } /$roomId /messages' )
250
289
.add (messageMap);
251
290
}
252
291
}
@@ -264,15 +303,18 @@ class FirebaseChatCore {
264
303
messageMap['updatedAt' ] = FieldValue .serverTimestamp ();
265
304
266
305
await FirebaseFirestore .instance
267
- .collection ('rooms /$roomId /messages' )
306
+ .collection ('${ config . roomsCollectionName } /$roomId /messages' )
268
307
.doc (message.id)
269
308
.update (messageMap);
270
309
}
271
310
272
311
/// Returns a stream of all users from Firebase
273
312
Stream <List <types.User >> users () {
274
313
if (firebaseUser == null ) return const Stream .empty ();
275
- return FirebaseFirestore .instance.collection ('users' ).snapshots ().map (
314
+ return FirebaseFirestore .instance
315
+ .collection (config.usersCollectionName)
316
+ .snapshots ()
317
+ .map (
276
318
(snapshot) => snapshot.docs.fold< List <types.User >> (
277
319
[],
278
320
(previousValue, doc) {
0 commit comments