FIRDatabase.m 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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/FirebaseDatabase/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. NSString *url = app.options.databaseURL;
  63. if (!url) {
  64. if (!app.options.projectID) {
  65. [NSException
  66. raise:@"MissingProjectId"
  67. format:@"Can't determine Firebase Database URL. Be sure to "
  68. @"include a Project ID when calling "
  69. @"`FirebaseApp.configure()`."];
  70. }
  71. FFLog(@"I-RDB024002", @"Using default host for project %@",
  72. app.options.projectID);
  73. url = [NSString
  74. stringWithFormat:@"https://%@-default-rtdb.firebaseio.com",
  75. app.options.projectID];
  76. }
  77. return [FIRDatabase databaseForApp:app URL:url];
  78. }
  79. + (FIRDatabase *)databaseForApp:(FIRApp *)app URL:(NSString *)url {
  80. if (app == nil) {
  81. [NSException raise:@"InvalidFIRApp"
  82. format:@"nil FIRApp instance passed to databaseForApp."];
  83. }
  84. if (url == nil) {
  85. [NSException raise:@"MissingDatabaseURL"
  86. format:@"Failed to get FirebaseDatabase instance: "
  87. @"Specify DatabaseURL within FIRApp or from your "
  88. @"databaseForApp:URL: call."];
  89. }
  90. id<FIRDatabaseProvider> provider =
  91. FIR_COMPONENT(FIRDatabaseProvider, app.container);
  92. return [provider databaseForApp:app URL:url];
  93. }
  94. + (NSString *)buildVersion {
  95. // TODO: Restore git hash when build moves back to git
  96. return [NSString stringWithFormat:@"%s_%s", FIREBASE_SEMVER, __DATE__];
  97. }
  98. + (FIRDatabase *)createDatabaseForTests:(FRepoInfo *)repoInfo
  99. config:(FIRDatabaseConfig *)config {
  100. FIRDatabase *db = [[FIRDatabase alloc] initWithApp:nil
  101. repoInfo:repoInfo
  102. config:config];
  103. [db ensureRepo];
  104. return db;
  105. }
  106. + (NSString *)sdkVersion {
  107. return [NSString stringWithUTF8String:FIREBASE_SEMVER];
  108. }
  109. + (void)setLoggingEnabled:(BOOL)enabled {
  110. [FUtilities setLoggingEnabled:enabled];
  111. FFLog(@"I-RDB024001", @"BUILD Version: %@", [FIRDatabase buildVersion]);
  112. }
  113. - (id)initWithApp:(FIRApp *)app
  114. repoInfo:(FRepoInfo *)info
  115. config:(FIRDatabaseConfig *)config {
  116. self = [super init];
  117. if (self != nil) {
  118. self->_repoInfo = info;
  119. self->_config = config;
  120. self->_app = app;
  121. }
  122. return self;
  123. }
  124. - (FIRDatabaseReference *)reference {
  125. [self ensureRepo];
  126. return [[FIRDatabaseReference alloc] initWithRepo:self.repo
  127. path:[FPath empty]];
  128. }
  129. - (FIRDatabaseReference *)referenceWithPath:(NSString *)path {
  130. [self ensureRepo];
  131. [FValidation validateFrom:@"referenceWithPath" validRootPathString:path];
  132. FPath *childPath = [[FPath alloc] initWith:path];
  133. return [[FIRDatabaseReference alloc] initWithRepo:self.repo path:childPath];
  134. }
  135. - (FIRDatabaseReference *)referenceFromURL:(NSString *)databaseUrl {
  136. [self ensureRepo];
  137. if (databaseUrl == nil) {
  138. [NSException raise:@"InvalidDatabaseURL"
  139. format:@"Invalid nil url passed to referenceFromURL:"];
  140. }
  141. FParsedUrl *parsedUrl = [FUtilities parseUrl:databaseUrl];
  142. [FValidation validateFrom:@"referenceFromURL:" validURL:parsedUrl];
  143. if (![parsedUrl.repoInfo.host isEqualToString:_repoInfo.host]) {
  144. [NSException
  145. raise:@"InvalidDatabaseURL"
  146. format:
  147. @"Invalid URL (%@) passed to getReference(). URL was expected "
  148. "to match configured Database URL: %@",
  149. databaseUrl, [self reference].URL];
  150. }
  151. return [[FIRDatabaseReference alloc] initWithRepo:self.repo
  152. path:parsedUrl.path];
  153. }
  154. - (void)purgeOutstandingWrites {
  155. [self ensureRepo];
  156. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  157. [self.repo purgeOutstandingWrites];
  158. });
  159. }
  160. - (void)goOnline {
  161. [self ensureRepo];
  162. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  163. [self.repo resume];
  164. });
  165. }
  166. - (void)goOffline {
  167. [self ensureRepo];
  168. dispatch_async([FIRDatabaseQuery sharedQueue], ^{
  169. [self.repo interrupt];
  170. });
  171. }
  172. - (void)setPersistenceEnabled:(BOOL)persistenceEnabled {
  173. [self assertUnfrozen:@"setPersistenceEnabled"];
  174. self->_config.persistenceEnabled = persistenceEnabled;
  175. }
  176. - (BOOL)persistenceEnabled {
  177. return self->_config.persistenceEnabled;
  178. }
  179. - (void)setPersistenceCacheSizeBytes:(NSUInteger)persistenceCacheSizeBytes {
  180. [self assertUnfrozen:@"setPersistenceCacheSizeBytes"];
  181. self->_config.persistenceCacheSizeBytes = persistenceCacheSizeBytes;
  182. }
  183. - (NSUInteger)persistenceCacheSizeBytes {
  184. return self->_config.persistenceCacheSizeBytes;
  185. }
  186. - (void)setCallbackQueue:(dispatch_queue_t)callbackQueue {
  187. [self assertUnfrozen:@"setCallbackQueue"];
  188. self->_config.callbackQueue = callbackQueue;
  189. }
  190. - (dispatch_queue_t)callbackQueue {
  191. return self->_config.callbackQueue;
  192. }
  193. - (void)assertUnfrozen:(NSString *)methodName {
  194. if (self.repo != nil) {
  195. [NSException
  196. raise:@"FIRDatabaseAlreadyInUse"
  197. format:@"Calls to %@ must be made before any other usage of "
  198. "FIRDatabase instance.",
  199. methodName];
  200. }
  201. }
  202. - (void)ensureRepo {
  203. if (self.repo == nil) {
  204. self.repo = [FRepoManager createRepo:self.repoInfo
  205. config:self.config
  206. database:self];
  207. }
  208. }
  209. @end