@@ -44,13 +44,16 @@ public sealed class FirebaseFirestore {
4444 private readonly FirebaseFirestoreSettings _settings ;
4545 private readonly TransactionManager _transactionManager ;
4646
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 ;
4953
5054 // 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 ) {
5457 _proxy = Util . NotNull ( proxy ) ;
5558 App = app ;
5659 app . AppDisposed += OnAppDisposed ;
@@ -63,6 +66,7 @@ private FirebaseFirestore(FirestoreProxy proxy, FirebaseApp app) {
6366
6467 _settings = new FirebaseFirestoreSettings ( proxy ) ;
6568 _transactionManager = new TransactionManager ( this , proxy ) ;
69+ _databaseName = database ;
6670 }
6771
6872 /// <summary>
@@ -99,9 +103,11 @@ private void Dispose() {
99103 _isInCppInstanceCache = false ;
100104 RemoveSelfFromInstanceCache ( ) ;
101105 }
102-
106+
103107 _proxy = null ;
104108 App = null ;
109+ _databaseName = null ;
110+
105111 } finally {
106112 _disposeLock . ReleaseWriterLock ( ) ;
107113 }
@@ -115,41 +121,65 @@ private void Dispose() {
115121 public FirebaseApp App { get ; private set ; }
116122
117123 /// <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> .
119125 /// </summary>
120126 /// <value>A <c>FirebaseFirestore</c> instance.</value>
121127 public static FirebaseFirestore DefaultInstance {
122128 get {
123129 FirebaseApp app = Util . NotNull ( FirebaseApp . DefaultInstance ) ;
124- return GetInstance ( app ) ;
130+ return GetInstance ( app , DefaultDatabase ) ;
125131 }
126132 }
127133
128134 /// <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> .
130136 /// </summary>
131137 /// <param name="app">The <c>FirebaseApp</c> for which to get a <c>FirebaseFirestore</c>
132138 /// instance.</param>
133139 /// <returns>A <c>FirebaseFirestore</c> instance.</returns>
134140 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 ) {
135164 Preconditions . CheckNotNull ( app , nameof ( app ) ) ;
165+ Preconditions . CheckNotNull ( database , nameof ( database ) ) ;
136166
137167 while ( true ) {
138168 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
141171 // `_instanceCache`; if it isn't then create the `FirebaseFirestore` instance, put it in the
142172 // cache, and return it.
143173 lock ( _instanceCache ) {
144- if ( ! _instanceCache . TryGetValue ( app , out firestore ) ) {
174+ if ( ! _instanceCache . TryGetValue ( key , out firestore ) ) {
145175 // NOTE: FirestoreProxy.GetInstance() returns an *owning* reference (see the %newobject
146176 // directive in firestore.SWIG); therefore, we must make sure that we *never* call
147177 // FirestoreProxy.GetInstance() when it would return a proxy for a C++ object that it
148178 // previously returned. Otherwise, if it did, then that C++ object would be deleted
149179 // 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 ;
153183 return firestore ;
154184 }
155185 }
@@ -557,7 +587,7 @@ public Task WaitForPendingWritesAsync() {
557587 /// used. Calling any other method will result in an error.
558588 ///
559589 /// 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 .
561591 ///
562592 /// <c>Terminate()</c> does not cancel any pending writes, and any tasks that are awaiting a
563593 /// 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) {
663693 private void RemoveSelfFromInstanceCache ( ) {
664694 lock ( _instanceCache ) {
665695 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 ) ;
668699 }
669700 }
670701 }
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+ }
671733 }
672734}
0 commit comments