@@ -44,13 +44,16 @@ public sealed class FirebaseFirestore {
44
44
private readonly FirebaseFirestoreSettings _settings ;
45
45
private readonly TransactionManager _transactionManager ;
46
46
47
- private static readonly IDictionary < FirebaseApp , FirebaseFirestore > _instanceCache =
48
- new Dictionary < FirebaseApp , FirebaseFirestore > ( ) ;
47
+ private static readonly IDictionary < FirestoreInstanceCacheKey , FirebaseFirestore > _instanceCache =
48
+ new Dictionary < FirestoreInstanceCacheKey , FirebaseFirestore > ( ) ;
49
+
50
+ private const string DefaultDatabase = "(default)" ;
51
+
52
+ private string _databaseName ;
49
53
50
54
// We rely on e.g. firestore.Document("a/b").Firestore returning the original Firestore
51
- // instance so it's important the constructor remains private and we only create one
52
- // FirebaseFirestore instance per FirebaseApp instance.
53
- private FirebaseFirestore ( FirestoreProxy proxy , FirebaseApp app ) {
55
+ // instance so it's important the constructor remains private.
56
+ private FirebaseFirestore ( FirestoreProxy proxy , FirebaseApp app , string database ) {
54
57
_proxy = Util . NotNull ( proxy ) ;
55
58
App = app ;
56
59
app . AppDisposed += OnAppDisposed ;
@@ -63,6 +66,7 @@ private FirebaseFirestore(FirestoreProxy proxy, FirebaseApp app) {
63
66
64
67
_settings = new FirebaseFirestoreSettings ( proxy ) ;
65
68
_transactionManager = new TransactionManager ( this , proxy ) ;
69
+ _databaseName = database ;
66
70
}
67
71
68
72
/// <summary>
@@ -99,9 +103,11 @@ private void Dispose() {
99
103
_isInCppInstanceCache = false ;
100
104
RemoveSelfFromInstanceCache ( ) ;
101
105
}
102
-
106
+
103
107
_proxy = null ;
104
108
App = null ;
109
+ _databaseName = null ;
110
+
105
111
} finally {
106
112
_disposeLock . ReleaseWriterLock ( ) ;
107
113
}
@@ -115,41 +121,65 @@ private void Dispose() {
115
121
public FirebaseApp App { get ; private set ; }
116
122
117
123
/// <summary>
118
- /// Gets the instance of <c>FirebaseFirestore</c> for the default <c>FirebaseApp</c>.
124
+ /// Gets the instance of <c>FirebaseFirestore</c> for the default <c>FirebaseApp</c> with the default <c>database name</c> .
119
125
/// </summary>
120
126
/// <value>A <c>FirebaseFirestore</c> instance.</value>
121
127
public static FirebaseFirestore DefaultInstance {
122
128
get {
123
129
FirebaseApp app = Util . NotNull ( FirebaseApp . DefaultInstance ) ;
124
- return GetInstance ( app ) ;
130
+ return GetInstance ( app , DefaultDatabase ) ;
125
131
}
126
132
}
127
133
128
134
/// <summary>
129
- /// Gets an instance of <c>FirebaseFirestore</c> for a specific <c>FirebaseApp</c>.
135
+ /// Gets an instance of <c>FirebaseFirestore</c> for a specific <c>FirebaseApp</c> with the default <c>database name</c> .
130
136
/// </summary>
131
137
/// <param name="app">The <c>FirebaseApp</c> for which to get a <c>FirebaseFirestore</c>
132
138
/// instance.</param>
133
139
/// <returns>A <c>FirebaseFirestore</c> instance.</returns>
134
140
public static FirebaseFirestore GetInstance ( FirebaseApp app ) {
141
+ return GetInstance ( app , DefaultDatabase ) ;
142
+ }
143
+
144
+
145
+ /// <summary>
146
+ /// Gets an instance of <c>FirebaseFirestore</c> for the default <c>FirebaseApp</c> with a spesific <c>database name</c>.
147
+ /// </summary>
148
+ /// <param name="database">The customized name for the <c>database</c>.
149
+ /// instance.</param>
150
+ /// <returns>A <c>FirebaseFirestore</c> instance.</returns>
151
+ public static FirebaseFirestore GetInstance ( string database ) {
152
+ FirebaseApp app = Util . NotNull ( FirebaseApp . DefaultInstance ) ;
153
+ return GetInstance ( app , database ) ;
154
+ }
155
+
156
+ /// <summary>
157
+ /// Gets an instance of <c>FirebaseFirestore</c> for a specific <c>FirebaseApp</c> with a spesific <c>database name</c>.
158
+ /// </summary>
159
+ /// <param name="app">The <c>FirebaseApp</c> for which to get a <c>FirebaseFirestore</c>
160
+ /// <param name="database">The customized name for the <c>database</c>.
161
+ /// instance.</param>
162
+ /// <returns>A <c>FirebaseFirestore</c> instance.</returns>
163
+ public static FirebaseFirestore GetInstance ( FirebaseApp app , string database ) {
135
164
Preconditions . CheckNotNull ( app , nameof ( app ) ) ;
165
+ Preconditions . CheckNotNull ( database , nameof ( database ) ) ;
136
166
137
167
while ( true ) {
138
168
FirebaseFirestore firestore ;
139
-
140
- // Acquire the lock on `_instanceCache` to see if the given `FirebaseApp ` is in
169
+ FirestoreInstanceCacheKey key = new FirestoreInstanceCacheKey ( app , database ) ;
170
+ // Acquire the lock on `_instanceCache` to see if the given `FirestoreInstanceCacheKey ` is in
141
171
// `_instanceCache`; if it isn't then create the `FirebaseFirestore` instance, put it in the
142
172
// cache, and return it.
143
173
lock ( _instanceCache ) {
144
- if ( ! _instanceCache . TryGetValue ( app , out firestore ) ) {
174
+ if ( ! _instanceCache . TryGetValue ( key , out firestore ) ) {
145
175
// NOTE: FirestoreProxy.GetInstance() returns an *owning* reference (see the %newobject
146
176
// directive in firestore.SWIG); therefore, we must make sure that we *never* call
147
177
// FirestoreProxy.GetInstance() when it would return a proxy for a C++ object that it
148
178
// previously returned. Otherwise, if it did, then that C++ object would be deleted
149
179
// twice, causing a crash.
150
- FirestoreProxy firestoreProxy = Util . NotNull ( FirestoreProxy . GetInstance ( app ) ) ;
151
- firestore = new FirebaseFirestore ( firestoreProxy , app ) ;
152
- _instanceCache [ app ] = firestore ;
180
+ FirestoreProxy firestoreProxy = Util . NotNull ( FirestoreProxy . GetInstance ( app , database ) ) ;
181
+ firestore = new FirebaseFirestore ( firestoreProxy , app , database ) ;
182
+ _instanceCache [ key ] = firestore ;
153
183
return firestore ;
154
184
}
155
185
}
@@ -557,7 +587,7 @@ public Task WaitForPendingWritesAsync() {
557
587
/// used. Calling any other method will result in an error.
558
588
///
559
589
/// To restart after termination, simply create a new instance of <c>FirebaseFirestore</c> with
560
- /// <c>GetInstance()</c> or <c>GetInstance(FirebaseApp)</c> .
590
+ /// <c>GetInstance()</c> methods .
561
591
///
562
592
/// <c>Terminate()</c> does not cancel any pending writes, and any tasks that are awaiting a
563
593
/// response from the server will not be resolved. The next time you start this instance, it
@@ -663,10 +693,42 @@ private void WithFirestoreProxy(Action<FirestoreProxy> action) {
663
693
private void RemoveSelfFromInstanceCache ( ) {
664
694
lock ( _instanceCache ) {
665
695
FirebaseFirestore cachedFirestore ;
666
- if ( _instanceCache . TryGetValue ( App , out cachedFirestore ) && cachedFirestore == this ) {
667
- _instanceCache . Remove ( App ) ;
696
+ FirestoreInstanceCacheKey key = new FirestoreInstanceCacheKey ( App , _databaseName ) ;
697
+ if ( _instanceCache . TryGetValue ( key , out cachedFirestore ) && cachedFirestore == this ) {
698
+ _instanceCache . Remove ( key ) ;
668
699
}
669
700
}
670
701
}
702
+
703
+ private struct FirestoreInstanceCacheKey : IEquatable < FirestoreInstanceCacheKey > {
704
+ public FirebaseApp App { get ; }
705
+ public string DatabaseName { get ; }
706
+
707
+ public FirestoreInstanceCacheKey ( FirebaseApp app , string databaseName )
708
+ {
709
+ App = app ;
710
+ DatabaseName = databaseName ;
711
+ }
712
+
713
+ public override int GetHashCode ( ) {
714
+ return App . Name . GetHashCode ( ) + DatabaseName . GetHashCode ( ) ;
715
+ }
716
+ public override bool Equals ( object obj ) {
717
+ return obj is FirestoreInstanceCacheKey && Equals ( ( FirestoreInstanceCacheKey ) obj ) ;
718
+ }
719
+ public bool Equals ( FirestoreInstanceCacheKey other ) {
720
+ return App . Name == other . App . Name && DatabaseName == other . DatabaseName ;
721
+ }
722
+
723
+ public static bool operator == ( FirestoreInstanceCacheKey lhs , FirestoreInstanceCacheKey rhs ) {
724
+ return lhs . Equals ( rhs ) ;
725
+ }
726
+ public static bool operator != ( FirestoreInstanceCacheKey lhs , FirestoreInstanceCacheKey rhs ) {
727
+ return ! lhs . Equals ( rhs ) ;
728
+ }
729
+ public override string ToString ( ) {
730
+ return String . Format ( "FirestoreInstanceKey: App = {0}, DatabaseName = {1}" , App . Name , DatabaseName ) ;
731
+ }
732
+ }
671
733
}
672
734
}
0 commit comments