FIRDatabase.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <Foundation/Foundation.h>
  17. #import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
  18. #import "Interop/Auth/Public/FIRAuthInterop.h"
  19. #import "FirebaseDatabase/Sources/Api/FIRDatabaseComponent.h"
  20. #import "FirebaseDatabase/Sources/Api/Private/FIRDatabaseQuery_Private.h"
  21. #import "FirebaseDatabase/Sources/Api/Private/FIRDatabaseReference_Private.h"
  22. #import "FirebaseDatabase/Sources/Api/Private/FIRDatabase_Private.h"
  23. #import "FirebaseDatabase/Sources/Core/FRepoInfo.h"
  24. #import "FirebaseDatabase/Sources/FIRDatabaseConfig_Private.h"
  25. #import "FirebaseDatabase/Sources/Public/FIRDatabase.h"
  26. #import "FirebaseDatabase/Sources/Utilities/FValidation.h"
  27. @implementation FIRDatabase
  28. // The STR and STR_EXPAND macro allow a numeric version passed to he compiler
  29. // driver with a -D to be treated as a string instead of an invalid floating
  30. // point value.
  31. #define STR(x) STR_EXPAND(x)
  32. #define STR_EXPAND(x) #x
  33. static const char *FIREBASE_SEMVER = (const char *)STR(FIRDatabase_VERSION);
  34. + (FIRDatabase *)database {
  35. if (![FIRApp isDefaultAppConfigured]) {
  36. [NSException raise:@"FIRAppNotConfigured"
  37. format:@"Failed to get default Firebase Database instance. "
  38. @"Must call `[FIRApp "
  39. @"configure]` (`FirebaseApp.configure()` in Swift) "
  40. @"before using "
  41. @"Firebase Database."];
  42. }
  43. return [FIRDatabase databaseForApp:[FIRApp defaultApp]];
  44. }
  45. + (FIRDatabase *)databaseWithURL:(NSString *)url {
  46. FIRApp *app = [FIRApp defaultApp];
  47. if (app == nil) {
  48. [NSException
  49. raise:@"FIRAppNotConfigured"
  50. format:
  51. @"Failed to get default Firebase Database instance. "
  52. @"Must call `[FIRApp configure]` (`FirebaseApp.configure()` in "
  53. @"Swift) before using Firebase Database."];
  54. }
  55. return [FIRDatabase databaseForApp:app URL:url];
  56. }
  57. + (FIRDatabase *)databaseForApp:(FIRApp *)app {
  58. if (app == nil) {
  59. [NSException raise:@"InvalidFIRApp"
  60. format:@"nil FIRApp instance passed to databaseForApp."];
  61. }
  62. return [FIRDatabase databaseForApp:app URL:app.options.databaseURL];
  63. }
  64. + (FIRDatabase *)databaseForApp:(FIRApp *)app URL:(NSString *)url {
  65. if (app == nil) {
  66. [NSException raise:@"InvalidFIRApp"
  67. format:@"nil FIRApp instance passed to databaseForApp."];
  68. }
  69. if (url == nil) {
  70. [NSException raise:@"MissingDatabaseURL"
  71. format:@"Failed to get FirebaseDatabase instance: "
  72. @"Specify DatabaseURL within FIRApp or from your "
  73. @"databaseForApp:URL: call."];
  74. }
  75. id<FIRDatabaseProvider> provider =
  76. FIR_COMPONENT(FIRDatabaseProvider, app.container);
  77. return [provider databaseForApp:app URL:url];
  78. }
  79. + (NSString *)buildVersion {
  80. // TODO: Restore git hash when build moves back to git
  81. return [NSString stringWithFormat:@"%s_%s", FIREBASE_SEMVER, __DATE__];
  82. }
  83. + (FIRDatabase *)createDatabaseForTests:(FRepoInfo *)repoInfo
  84. config:(FIRDatabaseConfig *)config {
  85. FIRDatabase *db = [[FIRDatabase alloc] initWithApp:nil
  86. repoInfo:repoInfo
  87. config:config];
  88. [db ensureRepo];
  89. return db;
  90. }
  91. + (NSString *)sdkVersion {
  92. return [NSString stringWithUTF8String:FIREBASE_SEMVER];
  93. }
  94. + (void)setLoggingEnabled:(BOOL)enabled {
  95. [FUtilities setLoggingEnabled:enabled];
  96. FFLog(@"I-RDB024001", @"BUILD Version: %@", [FIRDatabase buildVersion]);
  97. }
  98. - (id)initWithApp:(FIRApp *)app
  99. repoInfo:(FRepoInfo *)info
  100. config:(FIRDatabaseConfig *)config {
  101. self = [super init];
  102. if (self != nil) {
  103. self->_repoInfo = info;
  104. self->_config = config;
  105. self->_app = app;
  106. }
  107. return self;
  108. }
  109. - (FIRDatabaseReference *)reference {
  110. [self ensureRepo];
  111. return [[FIRDatabaseReference alloc] initWithRepo:self.repo
  112. path:[FPath empty]];
  113. }
  114. - (FIRDatabaseReference *)referenceWithPath:(NSString *)path {
  115. [self ensureRepo];
  116. [FValidation validateFrom:@"referenceWithPath" validRootPathString:path];
  117. FPath *childPath = [[FPath alloc] initWith:path];
  118. return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:childPath];
  119. }
  120. - (FIRDatabaseReference *)referenceFromURL:(NSString *)databaseUrl {
  121. [self ensureRepo];
  122. if (databaseUrl == nil) {
  123. [NSException raise:@"InvalidDatabaseURL"
  124. format:@"Invalid nil url passed to referenceFromURL:"];
  125. }
  126. FParsedUrl *parsedUrl = [FUtilities parseUrl:databaseUrl];
  127. [FValidation validateFrom:@"referenceFromURL:" validURL:parsedUrl];
  128. if (![parsedUrl.repoInfo.host isEqualToString:_repoInfo.host]) {
  129. [NSException
  130. raise:@"InvalidDatabaseURL"
  131. format:
  132. @"Invalid URL (%@) passed to getReference(). URL was expected "
  133. "to match configured Database URL: %@",
  134. databaseUrl, [self reference].URL];
  135. }
  136. return [[FIRDatabaseReference alloc] initWithRepo:self.repo
  137. path:parsedUrl.path];
  138. }
  139. - (void)purgeOutstandingWrites {
  140. [self ensureRepo];
  141. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  142. [self.repo purgeOutstandingWrites];
  143. });
  144. }
  145. - (void)goOnline {
  146. [self ensureRepo];
  147. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  148. [self.repo resume];
  149. });
  150. }
  151. - (void)goOffline {
  152. [self ensureRepo];
  153. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  154. [self.repo interrupt];
  155. });
  156. }
  157. - (void)setPersistenceEnabled:(BOOL)persistenceEnabled {
  158. [self assertUnfrozen:@"setPersistenceEnabled"];
  159. self->_config.persistenceEnabled = persistenceEnabled;
  160. }
  161. - (BOOL)persistenceEnabled {
  162. return self->_config.persistenceEnabled;
  163. }
  164. - (void)setPersistenceCacheSizeBytes:(NSUInteger)persistenceCacheSizeBytes {
  165. [self assertUnfrozen:@"setPersistenceCacheSizeBytes"];
  166. self->_config.persistenceCacheSizeBytes = persistenceCacheSizeBytes;
  167. }
  168. - (NSUInteger)persistenceCacheSizeBytes {
  169. return self->_config.persistenceCacheSizeBytes;
  170. }
  171. - (void)setCallbackQueue:(dispatch_queue_t)callbackQueue {
  172. [self assertUnfrozen:@"setCallbackQueue"];
  173. self->_config.callbackQueue = callbackQueue;
  174. }
  175. - (dispatch_queue_t)callbackQueue {
  176. return self->_config.callbackQueue;
  177. }
  178. - (void)assertUnfrozen:(NSString *)methodName {
  179. if (self.repo != nil) {
  180. [NSException
  181. raise:@"FIRDatabaseAlreadyInUse"
  182. format:@"Calls to %@ must be made before any other usage of "
  183. "FIRDatabase instance.",
  184. methodName];
  185. }
  186. }
  187. - (void)ensureRepo {
  188. if (self.repo == nil) {
  189. self.repo = [FRepoManager createRepo:self.repoInfo
  190. config:self.config
  191. database:self];
  192. }
  193. }
  194. @end