diff --git a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java index a6c3d31c..d4bc7a1f 100644 --- a/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java +++ b/android/src/main/java/io/invertase/firebase/auth/RNFirebaseAuth.java @@ -1059,13 +1059,13 @@ class RNFirebaseAuth extends ReactContextBaseJavaModule { */ private AuthCredential getCredentialForProvider(String provider, String authToken, String authSecret) { switch (provider) { - case "facebook": + case "facebook.com": return FacebookAuthProvider.getCredential(authToken); - case "google": + case "google.com": return GoogleAuthProvider.getCredential(authToken, authSecret); - case "twitter": + case "twitter.com": return TwitterAuthProvider.getCredential(authToken, authSecret); - case "github": + case "github.com": return GithubAuthProvider.getCredential(authToken); case "phone": return PhoneAuthProvider.getCredential(authToken, authSecret); diff --git a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java index 3cb96896..8139e527 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java +++ b/android/src/main/java/io/invertase/firebase/firestore/FirestoreSerialize.java @@ -25,12 +25,14 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; import io.invertase.firebase.Utils; public class FirestoreSerialize { private static final String TAG = "FirestoreSerialize"; - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + private static final DateFormat READ_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + private static final DateFormat WRITE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); private static final String KEY_CHANGES = "changes"; private static final String KEY_DATA = "data"; private static final String KEY_DOC_CHANGE_DOCUMENT = "document"; @@ -41,6 +43,12 @@ public class FirestoreSerialize { private static final String KEY_METADATA = "metadata"; private static final String KEY_PATH = "path"; + static { + // Javascript Date.toISOString is always formatted to UTC + // We set the read TimeZone to UTC to account for this + READ_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + } + /** * Convert a DocumentSnapshot instance into a React Native WritableMap * @@ -212,7 +220,7 @@ public class FirestoreSerialize { typeMap.putMap("value", geoPoint); } else if (value instanceof Date) { typeMap.putString("type", "date"); - typeMap.putString("value", DATE_FORMAT.format((Date) value)); + typeMap.putString("value", WRITE_DATE_FORMAT.format((Date) value)); } else { // TODO: Changed to log an error rather than crash - is this correct? Log.e(TAG, "buildTypeMap: Cannot convert object of type " + value.getClass()); @@ -269,7 +277,7 @@ public class FirestoreSerialize { } else if ("date".equals(type)) { try { String date = typeMap.getString("value"); - return DATE_FORMAT.parse(date); + return READ_DATE_FORMAT.parse(date); } catch (ParseException exception) { Log.e(TAG, "parseTypeMap", exception); return null; diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java index cf01f262..d89c3093 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java +++ b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestore.java @@ -111,18 +111,6 @@ public class RNFirebaseFirestore extends ReactContextBaseJavaModule { }); } - @ReactMethod - public void documentCollections(String appName, String path, final Promise promise) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.collections(promise); - } - - @ReactMethod - public void documentCreate(String appName, String path, ReadableMap data, final Promise promise) { - RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); - ref.create(data, promise); - } - @ReactMethod public void documentDelete(String appName, String path, final Promise promise) { RNFirebaseFirestoreDocumentReference ref = getDocumentForAppPath(appName, path); diff --git a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java index 156d08e2..93862c99 100644 --- a/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java +++ b/android/src/main/java/io/invertase/firebase/firestore/RNFirebaseFirestoreDocumentReference.java @@ -40,14 +40,6 @@ public class RNFirebaseFirestoreDocumentReference { this.ref = RNFirebaseFirestore.getFirestoreForApp(appName).document(path); } - public void collections(Promise promise) { - // Not supported on Android - } - - public void create(ReadableMap data, Promise promise) { - // Not supported on Android out of the box - } - public void delete(final Promise promise) { this.ref.delete().addOnCompleteListener(new OnCompleteListener() { @Override diff --git a/ios/RNFirebase/auth/RNFirebaseAuth.m b/ios/RNFirebase/auth/RNFirebaseAuth.m index ba6cd293..66a60dfb 100644 --- a/ios/RNFirebase/auth/RNFirebaseAuth.m +++ b/ios/RNFirebase/auth/RNFirebaseAuth.m @@ -794,7 +794,15 @@ RCT_EXPORT_METHOD(unlink: if (error) { [self promiseRejectAuthException:reject error:error]; } else { - [self promiseWithUser:resolve rejecter:reject user:_user]; + // This is here to protect against bugs in the iOS SDK which don't + // correctly refresh the user object when unlinking certain accounts + [user reloadWithCompletion:^(NSError * _Nullable error) { + if (error) { + [self promiseRejectAuthException:reject error:error]; + } else { + [self promiseWithUser:resolve rejecter:reject user:user]; + } + }]; } }]; } else { @@ -889,15 +897,15 @@ RCT_EXPORT_METHOD(fetchProvidersForEmail: - (FIRAuthCredential *)getCredentialForProvider:(NSString *)provider token:(NSString *)authToken secret:(NSString *)authTokenSecret { FIRAuthCredential *credential; - if ([provider compare:@"twitter" options:NSCaseInsensitiveSearch] == NSOrderedSame) { + if ([provider compare:@"twitter.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRTwitterAuthProvider credentialWithToken:authToken secret:authTokenSecret]; - } else if ([provider compare:@"facebook" options:NSCaseInsensitiveSearch] == NSOrderedSame) { + } else if ([provider compare:@"facebook.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRFacebookAuthProvider credentialWithAccessToken:authToken]; - } else if ([provider compare:@"google" options:NSCaseInsensitiveSearch] == NSOrderedSame) { + } else if ([provider compare:@"google.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRGoogleAuthProvider credentialWithIDToken:authToken accessToken:authTokenSecret]; } else if ([provider compare:@"password" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIREmailAuthProvider credentialWithEmail:authToken password:authTokenSecret]; - } else if ([provider compare:@"github" options:NSCaseInsensitiveSearch] == NSOrderedSame) { + } else if ([provider compare:@"github.com" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [FIRGitHubAuthProvider credentialWithToken:authToken]; } else if ([provider compare:@"phone" options:NSCaseInsensitiveSearch] == NSOrderedSame) { credential = [[FIRPhoneAuthProvider provider] credentialWithVerificationID:authToken verificationCode:authTokenSecret]; diff --git a/ios/RNFirebase/database/RNFirebaseDatabase.m b/ios/RNFirebase/database/RNFirebaseDatabase.m index 9422cba0..70efdf8d 100644 --- a/ios/RNFirebase/database/RNFirebaseDatabase.m +++ b/ios/RNFirebase/database/RNFirebaseDatabase.m @@ -246,10 +246,12 @@ RCT_EXPORT_METHOD(on:(NSString *) appName RCT_EXPORT_METHOD(off:(NSString *) key eventRegistrationKey:(NSString *) eventRegistrationKey) { RNFirebaseDatabaseReference *ref = _dbReferences[key]; - [ref removeEventListener:eventRegistrationKey]; + if (ref) { + [ref removeEventListener:eventRegistrationKey]; - if (![ref hasListeners]) { - [_dbReferences removeObjectForKey:key]; + if (![ref hasListeners]) { + [_dbReferences removeObjectForKey:key]; + } } } diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestore.m b/ios/RNFirebase/firestore/RNFirebaseFirestore.m index 14de1efb..c9510f47 100644 --- a/ios/RNFirebase/firestore/RNFirebaseFirestore.m +++ b/ios/RNFirebase/firestore/RNFirebaseFirestore.m @@ -85,21 +85,6 @@ RCT_EXPORT_METHOD(documentBatch:(NSString *) appName }]; } -RCT_EXPORT_METHOD(documentCollections:(NSString *) appName - path:(NSString *) path - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - [[self getDocumentForAppPath:appName path:path] get:resolve rejecter:reject]; -} - -RCT_EXPORT_METHOD(documentCreate:(NSString *) appName - path:(NSString *) path - data:(NSDictionary *) data - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject) { - [[self getDocumentForAppPath:appName path:path] create:data resolver:resolve rejecter:reject]; -} - RCT_EXPORT_METHOD(documentDelete:(NSString *) appName path:(NSString *) path resolver:(RCTPromiseResolveBlock) resolve diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h index 98f70b3f..f3178e8c 100644 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h +++ b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.h @@ -17,8 +17,6 @@ @property FIRDocumentReference *ref; - (id)initWithPath:(RCTEventEmitter *)emitter app:(NSString *)app path:(NSString *)path; -- (void)collections:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; -- (void)create:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)delete:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)get:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; + (void)offSnapshot:(NSString *)listenerId; diff --git a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m index 4b1635f2..caa5495f 100644 --- a/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m +++ b/ios/RNFirebase/firestore/RNFirebaseFirestoreDocumentReference.m @@ -23,17 +23,6 @@ static NSMutableDictionary *_listeners; return self; } -- (void)collections:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject { - // Not supported on iOS -} - -- (void)create:(NSDictionary *) data - resolver:(RCTPromiseResolveBlock) resolve - rejecter:(RCTPromiseRejectBlock) reject { - // Not supported on iOS out of the box -} - - (void)delete:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject { [_ref deleteDocumentWithCompletion:^(NSError * _Nullable error) { @@ -176,7 +165,7 @@ static NSMutableDictionary *_listeners; NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj]; map[key] = typeMap; }]; - + return map; } @@ -186,7 +175,7 @@ static NSMutableDictionary *_listeners; NSDictionary *typeMap = [RNFirebaseFirestoreDocumentReference buildTypeMap:obj]; [array addObject:typeMap]; }]; - + return array; } @@ -231,7 +220,7 @@ static NSMutableDictionary *_listeners; // TODO: Log an error typeMap[@"type"] = @"null"; } - + return typeMap; } diff --git a/lib/modules/auth/providers/FacebookAuthProvider.js b/lib/modules/auth/providers/FacebookAuthProvider.js index d30c190f..c8abbc10 100644 --- a/lib/modules/auth/providers/FacebookAuthProvider.js +++ b/lib/modules/auth/providers/FacebookAuthProvider.js @@ -1,4 +1,4 @@ -const providerId = 'facebook'; +const providerId = 'facebook.com'; export default class FacebookAuthProvider { constructor() { diff --git a/lib/modules/auth/providers/GithubAuthProvider.js b/lib/modules/auth/providers/GithubAuthProvider.js index afbfa37b..fbd84272 100644 --- a/lib/modules/auth/providers/GithubAuthProvider.js +++ b/lib/modules/auth/providers/GithubAuthProvider.js @@ -1,4 +1,4 @@ -const providerId = 'github'; +const providerId = 'github.com'; export default class GithubAuthProvider { constructor() { diff --git a/lib/modules/auth/providers/GoogleAuthProvider.js b/lib/modules/auth/providers/GoogleAuthProvider.js index 4a9bac49..eda9f241 100644 --- a/lib/modules/auth/providers/GoogleAuthProvider.js +++ b/lib/modules/auth/providers/GoogleAuthProvider.js @@ -1,4 +1,4 @@ -const providerId = 'google'; +const providerId = 'google.com'; export default class GoogleAuthProvider { constructor() { diff --git a/lib/modules/auth/providers/TwitterAuthProvider.js b/lib/modules/auth/providers/TwitterAuthProvider.js index feddf6ab..15c0a2f6 100644 --- a/lib/modules/auth/providers/TwitterAuthProvider.js +++ b/lib/modules/auth/providers/TwitterAuthProvider.js @@ -1,4 +1,4 @@ -const providerId = 'twitter'; +const providerId = 'twitter.com'; export default class TwitterAuthProvider { constructor() { diff --git a/lib/modules/database/reference.js b/lib/modules/database/reference.js index 735eca99..ab3a1da9 100644 --- a/lib/modules/database/reference.js +++ b/lib/modules/database/reference.js @@ -74,7 +74,6 @@ export default class Reference extends ReferenceBase { this._refListeners = {}; this._database = database; this._query = new Query(this, path, existingModifiers); - this.log = this._database.log; this.log.debug('Created new Reference', this._getRefKey()); } diff --git a/package-lock.json b/package-lock.json index c439794a..d699d662 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-native-firebase", - "version": "3.0.3", + "version": "3.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/tests/src/tests/firestore/documentReferenceTests.js b/tests/src/tests/firestore/documentReferenceTests.js index bc4a39e0..968cb28b 100644 --- a/tests/src/tests/firestore/documentReferenceTests.js +++ b/tests/src/tests/firestore/documentReferenceTests.js @@ -426,13 +426,15 @@ function documentReferenceTests({ describe, it, context, firebase }) { context('types', () => { it('should handle Date field', async () => { + const date = new Date(); const docRef = firebase.native.firestore().doc('document-tests/reference'); await docRef.set({ - field: new Date(), + field: date, }); const doc = await docRef.get(); doc.data().field.should.be.instanceof(Date); + should.equal(doc.data().field.toISOString(), date.toISOString()); }); });