Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement RTDB Query get #7110

Merged
merged 17 commits into from
Jan 6, 2021
2 changes: 1 addition & 1 deletion FirebaseDatabase/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Unreleased
- [added] Made emulator connection API consistent between Auth, Database, Firestore, and Functions (#5916).
- [added] Implement RTDB Query get (#7110)
- [added] Added FIRDatabaseQuery#getDataWithCompletionBlock which returns data from the server when cache is stale (#7110).

# v7.0.0
- [fixed] Disabled a deprecation warning. (#6502)
Expand Down
2 changes: 1 addition & 1 deletion FirebaseDatabase/Sources/Api/FIRDatabaseQuery.m
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ - (void)keepSynced:(BOOL)keepSynced {
- (void)getDataWithCompletionBlock:(void (^)(NSError *__nullable error,
FIRDataSnapshot *snapshot))block {
dispatch_async([FIRDatabaseQuery sharedQueue], ^{
[self.repo getValue:self withCompletionBlock:block];
[self.repo getData:self withCompletionBlock:block];
});
}

Expand Down
4 changes: 2 additions & 2 deletions FirebaseDatabase/Sources/Constants/FConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,11 @@ FOUNDATION_EXPORT NSString *const kFWPRequestStatus;
FOUNDATION_EXPORT NSString *const kWireProtocolVersionParam;
FOUNDATION_EXPORT NSString *const kWebsocketProtocolVersion;
FOUNDATION_EXPORT NSString *const kWebsocketServerKillPacket;
FOUNDATION_EXPORT NSString *const kPersistentConnOffline;
FOUNDATION_EXPORT NSString *const kPersistentConnectionOffline;
FOUNDATION_EXPORT const int kWebsocketMaxFrameSize;
FOUNDATION_EXPORT NSUInteger const kWebsocketKeepaliveInterval;
FOUNDATION_EXPORT NSUInteger const kWebsocketConnectTimeout;
FOUNDATION_EXPORT UInt64 const kPersistentConnGetConnectTimeout;
FOUNDATION_EXPORT UInt64 const kPersistentConnectionGetConnectTimeout;

FOUNDATION_EXPORT float const kPersistentConnReconnectMinDelay;
FOUNDATION_EXPORT float const kPersistentConnReconnectMaxDelay;
Expand Down
4 changes: 2 additions & 2 deletions FirebaseDatabase/Sources/Constants/FConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@
NSString *const kWireProtocolVersionParam = @"v";
NSString *const kWebsocketProtocolVersion = @"5";
NSString *const kWebsocketServerKillPacket = @"kill";
NSString *const kPersistentConnOffline = @"Client is offline.";
NSString *const kPersistentConnectionOffline = @"Client is offline.";
const int kWebsocketMaxFrameSize = 16384;
NSUInteger const kWebsocketKeepaliveInterval = 45;
NSUInteger const kWebsocketConnectTimeout = 30;
UInt64 const kPersistentConnGetConnectTimeout = 3 * NSEC_PER_SEC;
UInt64 const kPersistentConnectionGetConnectTimeout = 3 * NSEC_PER_SEC;

float const kPersistentConnReconnectMinDelay = 1.0;
float const kPersistentConnReconnectMaxDelay = 30.0;
Expand Down
47 changes: 26 additions & 21 deletions FirebaseDatabase/Sources/Core/FPersistentConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ - (BOOL)canSendWrites {
- (BOOL)canSendReads {
return self->connectionState == ConnectionStateConnected;
}

#pragma mark -
#pragma mark FConnection delegate methods

Expand Down Expand Up @@ -730,7 +731,8 @@ - (void)sendGet:(NSNumber *)index {
NSAssert([self canSendReads],
@"sendGet called when not able to send reads");
FOutstandingGet *get = self.outstandingGets[index];
assert(get != nil);
NSAssert(get != nil, @"sendGet found no outstanding get at index %@",
index);
if ([get sent]) {
return;
}
Expand Down Expand Up @@ -827,26 +829,27 @@ - (void)get:(NSString *)pathString
self.outstandingGets[index] = get;

if (![self connected]) {
dispatch_after(
dispatch_time(DISPATCH_TIME_NOW, kPersistentConnGetConnectTimeout),
self.dispatchQueue, ^{
FOutstandingGet *get = self.outstandingGets[index];
if ([get sent]) {
return;
}
get.sent = YES;
[self.outstandingGets removeObjectForKey:index];
get.onCompleteBlock(kFWPResponseForActionStatusFailed, nil,
kPersistentConnOffline);
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
kPersistentConnectionGetConnectTimeout),
self.dispatchQueue, ^{
FOutstandingGet *get = self.outstandingGets[index];
if ([get sent]) {
return;
}
FFLog(@"I-RDB034045",
@"get %@ timed out waiting for a connection",
index);
get.sent = YES;
[self.outstandingGets removeObjectForKey:index];
get.onCompleteBlock(kFWPResponseForActionStatusFailed,
nil, kPersistentConnectionOffline);
});
return;
}

if ([self canSendReads]) {
FFLog(@"I-RDB034024", @"Was connected, and added as index: %@", index);
[self sendGet:index];
} else {
FFLog(@"I-RDB034025", @"Was connected, and added as index: %@", index);
}
}

Expand Down Expand Up @@ -1089,12 +1092,13 @@ - (void)restoreState {
[self sendListen:outstandingListen];
}];

NSArray *keys = [[self.outstandingPuts allKeys]
NSArray *putKeys = [[self.outstandingPuts allKeys]
sortedArrayUsingSelector:@selector(compare:)];
for (int i = 0; i < [keys count]; i++) {
if ([self.outstandingPuts objectForKey:[keys objectAtIndex:i]] != nil) {
for (int i = 0; i < [putKeys count]; i++) {
if ([self.outstandingPuts objectForKey:[putKeys objectAtIndex:i]] !=
nil) {
FFLog(@"I-RDB034037", @"Restoring put: %d", i);
[self sendPut:[keys objectAtIndex:i]];
[self sendPut:[putKeys objectAtIndex:i]];
} else {
FFLog(@"I-RDB034038", @"Restoring put: skipped nil: %d", i);
}
Expand All @@ -1103,9 +1107,10 @@ - (void)restoreState {
NSArray *getKeys = [[self.outstandingGets allKeys]
sortedArrayUsingSelector:@selector(compare:)];
for (int i = 0; i < [getKeys count]; i++) {
if ([self.outstandingGets objectForKey:[keys objectAtIndex:i]] != nil) {
if ([self.outstandingGets objectForKey:[getKeys objectAtIndex:i]] !=
nil) {
FFLog(@"I-RDB034037", @"Restoring get: %d", i);
[self sendGet:[keys objectAtIndex:i]];
[self sendGet:[getKeys objectAtIndex:i]];
} else {
FFLog(@"I-RDB034038", @"Restoring get: skipped nil: %d", i);
}
Expand Down
2 changes: 1 addition & 1 deletion FirebaseDatabase/Sources/Core/FRepo.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
withCallback:(fbt_void_nserror_ref)callback;
- (void)purgeOutstandingWrites;

- (void)getValue:(FIRDatabaseQuery *)query
- (void)getData:(FIRDatabaseQuery *)query
withCompletionBlock:
(void (^_Nonnull)(NSError *__nullable error,
FIRDataSnapshot *__nullable snapshot))block;
Expand Down
2 changes: 1 addition & 1 deletion FirebaseDatabase/Sources/Core/FRepo.m
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ - (void)purgeOutstandingWrites {
[self.connection purgeOutstandingWrites];
}

- (void)getValue:(FIRDatabaseQuery *)query
- (void)getData:(FIRDatabaseQuery *)query
withCompletionBlock:
(void (^_Nonnull)(NSError *__nullable error,
FIRDataSnapshot *__nullable snapshot))block {
Expand Down
8 changes: 2 additions & 6 deletions FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* limitations under the License.
*/

#import "FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.h"
#import "FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h"
#import "FirebaseDatabase/Sources/Api/Private/FIRDatabaseQuery_Private.h"
#import "FirebaseDatabase/Sources/Constants/FConstants.h"
#import "FirebaseDatabase/Sources/Core/FQuerySpec.h"
#import "FirebaseDatabase/Sources/Utilities/FUtilities.h"
#import "FirebaseDatabase/Tests/Integration/FIRDatabaseQueryTests.h"
#import "FirebaseDatabase/Tests/Helpers/FIRFakeApp.h"
#import "FirebaseDatabase/Tests/Helpers/FTestExpectations.h"

Expand Down Expand Up @@ -3083,7 +3083,7 @@ - (void)testOfflineQueryGet {

[ref getDataWithCompletionBlock:^(NSError* err, FIRDataSnapshot* snapshot) {
XCTAssertNotNil(err);
XCTAssertEqualObjects([err localizedFailureReason], kPersistentConnOffline);
XCTAssertEqualObjects([err localizedFailureReason], kPersistentConnectionOffline);
done = YES;
}];

Expand Down Expand Up @@ -3127,13 +3127,9 @@ - (void)testQueryGetCached {
}
}];

WAIT_FOR(done);
done = NO;

[ref setValue:@42
withCompletionBlock:^(NSError* error, FIRDatabaseReference* ref) {
XCTAssertNil(error);
done = YES;
}];

WAIT_FOR(done);
Expand Down