@bigin/ns-firebase
Version:
1,419 lines • 77.3 kB
JavaScript
import { Application, Device } from '@nativescript/core';
import { DocumentSnapshot as DocumentSnapshotBase, FieldValue, firebase, GeoPoint, isDocumentReference } from './firebase-common';
import * as firebaseFunctions from './functions/functions';
import * as firebaseMessaging from './messaging/messaging';
import { firebaseUtils } from './utils';
import { getNonce, Sha256 } from './utils/nonce-util-ios';
export var QueryOrderByType;
(function (QueryOrderByType) {
QueryOrderByType[(QueryOrderByType['KEY'] = 0)] = 'KEY';
QueryOrderByType[(QueryOrderByType['VALUE'] = 1)] = 'VALUE';
QueryOrderByType[(QueryOrderByType['CHILD'] = 2)] = 'CHILD';
QueryOrderByType[(QueryOrderByType['PRIORITY'] = 3)] = 'PRIORITY';
})(QueryOrderByType || (QueryOrderByType = {}));
export var QueryRangeType;
(function (QueryRangeType) {
QueryRangeType[(QueryRangeType['START_AT'] = 0)] = 'START_AT';
QueryRangeType[(QueryRangeType['END_AT'] = 1)] = 'END_AT';
QueryRangeType[(QueryRangeType['EQUAL_TO'] = 2)] = 'EQUAL_TO';
})(QueryRangeType || (QueryRangeType = {}));
export var QueryLimitType;
(function (QueryLimitType) {
QueryLimitType[(QueryLimitType['FIRST'] = 0)] = 'FIRST';
QueryLimitType[(QueryLimitType['LAST'] = 1)] = 'LAST';
})(QueryLimitType || (QueryLimitType = {}));
firebase._gIDAuthentication = null;
firebase._cachedDynamicLink = null;
firebase._configured = false;
firebase._currentNonce = null;
const useExternalPushProvider = NSBundle.mainBundle.infoDictionary.objectForKey('UseExternalPushProvider') === true;
let initializeArguments;
class DocumentSnapshot extends DocumentSnapshotBase {
constructor(snapshot) {
super(snapshot.documentID, snapshot.exists, firebaseUtils.toJsObject(snapshot.data()), firebase.firestore._getDocumentReference(snapshot.reference));
this.snapshot = snapshot;
this.metadata = {
fromCache: this.snapshot.metadata.fromCache,
hasPendingWrites: this.snapshot.metadata.pendingWrites,
};
this.ios = snapshot;
}
}
firebase.authStateListener = null;
firebase.addOnMessageReceivedCallback = firebaseMessaging.addOnMessageReceivedCallback;
firebase.addOnPushTokenReceivedCallback = firebaseMessaging.addOnPushTokenReceivedCallback;
firebase.registerForPushNotifications = firebaseMessaging.registerForPushNotifications;
firebase.unregisterForPushNotifications = firebaseMessaging.unregisterForPushNotifications;
firebase.getCurrentPushToken = firebaseMessaging.getCurrentPushToken;
firebase.registerForInteractivePush = firebaseMessaging.registerForInteractivePush;
firebase.subscribeToTopic = firebaseMessaging.subscribeToTopic;
firebase.unsubscribeFromTopic = firebaseMessaging.unsubscribeFromTopic;
firebase.areNotificationsEnabled = firebaseMessaging.areNotificationsEnabled;
firebase.functions = firebaseFunctions;
NSNotificationCenter.defaultCenter.addObserverForNameObjectQueueUsingBlock(UIApplicationDidFinishLaunchingNotification, null, NSOperationQueue.mainQueue, (appNotification) => {
if (!firebase._configured) {
firebase._configured = true;
if (typeof FIRApp !== 'undefined') {
FIRApp.configure();
}
}
});
firebase.addAppDelegateMethods = (appDelegate) => {
if (typeof FIRMessaging !== 'undefined' || useExternalPushProvider || typeof FBSDKApplicationDelegate !== 'undefined') {
appDelegate.prototype.applicationDidFinishLaunchingWithOptions = (application, launchOptions) => {
if (launchOptions) {
const remoteNotification = launchOptions.objectForKey(UIApplicationLaunchOptionsRemoteNotificationKey);
if (remoteNotification) {
firebaseMessaging.handleRemoteNotification(application, remoteNotification);
}
}
if (typeof FBSDKApplicationDelegate !== 'undefined') {
FBSDKApplicationDelegate.sharedInstance.applicationDidFinishLaunchingWithOptions(application, launchOptions);
}
return true;
};
}
if (typeof FBSDKApplicationDelegate !== 'undefined' || typeof GIDSignIn !== 'undefined' || typeof FIRDynamicLink !== 'undefined') {
appDelegate.prototype.applicationOpenURLSourceApplicationAnnotation = (application, url, sourceApplication, annotation) => {
let result = false;
if (typeof FBSDKApplicationDelegate !== 'undefined') {
result = FBSDKApplicationDelegate.sharedInstance.applicationOpenURLSourceApplicationAnnotation(application, url, sourceApplication, annotation);
}
if (typeof GIDSignIn !== 'undefined') {
result = result || GIDSignIn.sharedInstance().handleURL(url);
}
if (typeof FIRDynamicLink !== 'undefined') {
const dynamicLink = FIRDynamicLinks.dynamicLinks().dynamicLinkFromCustomSchemeURL(url);
if (dynamicLink) {
console.log('Dynamic link from ' + sourceApplication + ', URL: ' + dynamicLink.url.absoluteString);
firebase._cachedDynamicLink = {
url: dynamicLink.url.absoluteString,
minimumAppVersion: dynamicLink.minimumAppVersion,
};
result = true;
}
}
return result;
};
}
if (typeof FBSDKApplicationDelegate !== 'undefined' || typeof GIDSignIn !== 'undefined' || typeof FIRDynamicLink !== 'undefined') {
appDelegate.prototype.applicationOpenURLOptions = (application, url, options) => {
let result = false;
if (typeof FBSDKApplicationDelegate !== 'undefined') {
result = FBSDKApplicationDelegate.sharedInstance.applicationOpenURLSourceApplicationAnnotation(application, url, options.valueForKey(UIApplicationOpenURLOptionsSourceApplicationKey), options.valueForKey(UIApplicationOpenURLOptionsAnnotationKey));
}
if (typeof GIDSignIn !== 'undefined') {
result = result || GIDSignIn.sharedInstance().handleURL(url);
}
if (typeof FIRDynamicLink !== 'undefined') {
const dynamicLinks = FIRDynamicLinks.dynamicLinks();
const dynamicLink = dynamicLinks.dynamicLinkFromCustomSchemeURL(url);
if (dynamicLink && dynamicLink.url !== null) {
if (firebase._dynamicLinkCallback) {
firebase._dynamicLinkCallback({
url: dynamicLink.url.absoluteString,
minimumAppVersion: dynamicLink.minimumAppVersion,
});
} else {
firebase._cachedDynamicLink = {
url: dynamicLink.url.absoluteString,
minimumAppVersion: dynamicLink.minimumAppVersion,
};
}
result = true;
}
}
return result;
};
}
if (typeof FIRDynamicLink !== 'undefined') {
appDelegate.prototype.applicationContinueUserActivityRestorationHandler = (application, userActivity, restorationHandler) => {
let result = false;
if (userActivity.webpageURL) {
const fAuth = typeof FIRAuth !== 'undefined' ? FIRAuth.auth() : undefined;
if (fAuth && fAuth.isSignInWithEmailLink(userActivity.webpageURL.absoluteString)) {
const rememberedEmail = firebase.getRememberedEmailForEmailLinkLogin();
if (rememberedEmail !== undefined) {
if (fAuth.currentUser) {
const onCompletionLink = (result, error) => {
if (error) {
fAuth.signInWithEmailLinkCompletion(rememberedEmail, userActivity.webpageURL.absoluteString, (authData, error) => {
if (!error) {
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(authData.user),
});
}
});
} else {
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(result.user),
});
}
};
const fIRAuthCredential = FIREmailAuthProvider.credentialWithEmailLink(rememberedEmail, userActivity.webpageURL.absoluteString);
fAuth.currentUser.linkWithCredentialCompletion(fIRAuthCredential, onCompletionLink);
} else {
fAuth.signInWithEmailLinkCompletion(rememberedEmail, userActivity.webpageURL.absoluteString, (authData, error) => {
if (error) {
console.log(error.localizedDescription);
} else {
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(authData.user),
});
}
});
}
}
result = true;
} else {
result = FIRDynamicLinks.dynamicLinks().handleUniversalLinkCompletion(userActivity.webpageURL, (dynamicLink, error) => {
if (dynamicLink !== null && dynamicLink.url !== null) {
if (firebase._dynamicLinkCallback) {
firebase._dynamicLinkCallback({
url: dynamicLink.url.absoluteString,
minimumAppVersion: dynamicLink.minimumAppVersion,
});
} else {
firebase._cachedDynamicLink = {
url: dynamicLink.url.absoluteString,
minimumAppVersion: dynamicLink.minimumAppVersion,
};
}
}
});
}
}
return result;
};
}
if (typeof FIRMessaging !== 'undefined' || useExternalPushProvider) {
firebaseMessaging.addBackgroundRemoteNotificationHandler(appDelegate);
}
};
firebase.fetchSignInMethodsForEmail = (email) => {
return new Promise((resolve, reject) => {
try {
if (typeof email !== 'string') {
reject('A parameter representing an email address is required.');
return;
}
FIRAuth.auth().fetchSignInMethodsForEmailCompletion(email, (methodsNSArray, error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve(firebaseUtils.toJsObject(methodsNSArray));
}
});
} catch (ex) {
console.log('Error in firebase.fetchSignInMethodsForEmail: ' + ex);
reject(ex);
}
});
};
firebase.addOnDynamicLinkReceivedCallback = (callback) => {
return new Promise((resolve, reject) => {
try {
if (typeof FIRDynamicLink === 'undefined') {
reject("Set 'dynamic_links' to 'true' in firebase.nativescript.json and remove the platforms/ios folder");
return;
}
firebase._dynamicLinkCallback = callback;
if (firebase._cachedDynamicLink !== null) {
callback(firebase._cachedDynamicLink);
firebase._cachedDynamicLink = null;
}
resolve();
} catch (ex) {
console.log('Error in firebase.addOnDynamicLinkReceivedCallback: ' + ex);
reject(ex);
}
});
};
if (typeof FIRMessaging !== 'undefined' || useExternalPushProvider) {
firebaseMessaging.prepAppDelegate();
}
function getAppDelegate() {
if (Application.ios.delegate === undefined) {
var UIApplicationDelegateImpl = /** @class */ (function (_super) {
__extends(UIApplicationDelegateImpl, _super);
function UIApplicationDelegateImpl() {
return (_super !== null && _super.apply(this, arguments)) || this;
}
UIApplicationDelegateImpl = __decorate([ObjCClass(UIApplicationDelegate)], UIApplicationDelegateImpl);
return UIApplicationDelegateImpl;
})(UIResponder);
Application.ios.delegate = UIApplicationDelegateImpl;
}
return Application.ios.delegate;
}
firebase.addAppDelegateMethods(getAppDelegate());
firebase.getCallbackData = (type, snapshot) => {
return {
type: type,
key: snapshot.key,
value: firebaseUtils.toJsObject(snapshot.value),
};
};
firebase.init = (arg) => {
return new Promise((resolve, reject) => {
if (firebase.initialized) {
reject('Firebase already initialized');
return;
}
firebase.initialized = true;
try {
try {
if (typeof FIRServerValue !== 'undefined') {
firebase.ServerValue = {
TIMESTAMP: FIRServerValue.timestamp(),
};
}
} catch (ignore) {}
arg = arg || {};
initializeArguments = arg;
if (FIROptions && FIROptions.defaultOptions() !== null) {
FIROptions.defaultOptions().deepLinkURLScheme = NSBundle.mainBundle.bundleIdentifier;
}
if (typeof FIRAnalytics !== 'undefined' && FIRAnalytics.setAnalyticsCollectionEnabled) {
FIRAnalytics.setAnalyticsCollectionEnabled(arg.analyticsCollectionEnabled !== false);
}
if (!firebase._configured) {
firebase._configured = true;
if (typeof FIRApp !== 'undefined') {
FIRApp.configure();
}
}
if (arg.crashlyticsCollectionEnabled && typeof Crashlytics !== 'undefined') {
Fabric.with(NSArray.arrayWithObject(Crashlytics.class()));
}
if (typeof FIRDatabase !== 'undefined') {
if (arg.persist) {
FIRDatabase.database().persistenceEnabled = true;
}
}
if (typeof FIRFirestore !== 'undefined') {
if (arg.persist === false) {
const fIRFirestoreSettings = FIRFirestoreSettings.new();
fIRFirestoreSettings.persistenceEnabled = false;
FIRFirestore.firestore().settings = fIRFirestoreSettings;
}
}
if (typeof FIRAuth !== 'undefined') {
if (arg.iOSEmulatorFlush) {
try {
FIRAuth.auth().signOut();
} catch (signOutErr) {
console.log('Sign out of Firebase error: ' + signOutErr);
}
}
if (arg.onAuthStateChanged) {
firebase.authStateListener = (auth, user) => {
arg.onAuthStateChanged({
loggedIn: user !== null,
user: toLoginResult(user),
});
};
FIRAuth.auth().addAuthStateDidChangeListener(firebase.authStateListener);
}
if (!firebase.authStateListener) {
firebase.authStateListener = (auth, user) => {
firebase.notifyAuthStateListeners({
loggedIn: user !== null,
user: toLoginResult(user),
});
};
FIRAuth.auth().addAuthStateDidChangeListener(firebase.authStateListener);
}
}
if (arg.onDynamicLinkCallback !== undefined) {
firebase.addOnDynamicLinkReceivedCallback(arg.onDynamicLinkCallback);
}
if (typeof FBSDKAppEvents !== 'undefined') {
FBSDKAppEvents.activateApp();
}
if (typeof FIRMessaging !== 'undefined') {
firebaseMessaging.initFirebaseMessaging(arg);
}
if (arg.storageBucket) {
if (typeof FIRStorage === 'undefined') {
reject("Uncomment Storage in the plugin's Podfile first");
return;
}
firebase.storageBucket = FIRStorage.storage().referenceForURL(arg.storageBucket);
}
resolve(typeof FIRDatabase !== 'undefined' ? FIRDatabase.database().reference() : undefined);
} catch (ex) {
console.log('Error in firebase.init: ' + ex);
reject(ex);
}
});
};
firebase.getRemoteConfig = (arg) => {
return new Promise((resolve, reject) => {
try {
if (typeof FIRRemoteConfig === 'undefined') {
reject("Uncomment RemoteConfig in the plugin's Podfile first");
return;
}
if (arg.properties === undefined) {
reject("Argument 'properties' is missing");
return;
}
const firebaseRemoteConfig = FIRRemoteConfig.remoteConfig();
firebaseRemoteConfig.configSettings = new FIRRemoteConfigSettings({ developerModeEnabled: arg.developerMode || false });
const dic = NSMutableDictionary.new();
for (let p in arg.properties) {
const prop = arg.properties[p];
if (prop.default !== undefined) {
dic.setObjectForKey(prop.default, prop.key);
}
}
firebaseRemoteConfig.setDefaults(dic);
const onCompletion = (remoteConfigFetchStatus, error) => {
if (remoteConfigFetchStatus === 1 || remoteConfigFetchStatus === 3) {
const activated = firebaseRemoteConfig.activateFetched();
const result = {
lastFetch: firebaseRemoteConfig.lastFetchTime,
throttled: remoteConfigFetchStatus === 3,
properties: {},
};
for (let p in arg.properties) {
const prop = arg.properties[p];
const key = prop.key;
const value = firebaseRemoteConfig.configValueForKey(key).stringValue;
result.properties[key] = firebase.strongTypeify(value);
}
resolve(result);
} else {
reject(error ? error.localizedDescription : 'Unknown error, fetch status: ' + remoteConfigFetchStatus);
}
};
const expirationDuration = arg.cacheExpirationSeconds || 43200;
firebaseRemoteConfig.fetchWithExpirationDurationCompletionHandler(expirationDuration, onCompletion);
} catch (ex) {
console.log('Error in firebase.getRemoteConfig: ' + ex);
reject(ex);
}
});
};
firebase.getCurrentUser = (arg) => {
return new Promise((resolve, reject) => {
try {
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
const user = fAuth.currentUser;
if (user) {
resolve(toLoginResult(user));
} else {
reject();
}
} catch (ex) {
console.log('Error in firebase.getCurrentUser: ' + ex);
reject(ex);
}
});
};
firebase.sendEmailVerification = (actionCodeSettings) => {
return new Promise((resolve, reject) => {
try {
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
const user = fAuth.currentUser;
if (user) {
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve(true);
}
};
if (actionCodeSettings) {
const firActionCodeSettings = FIRActionCodeSettings.new();
if (actionCodeSettings.handleCodeInApp !== undefined) {
firActionCodeSettings.handleCodeInApp = actionCodeSettings.handleCodeInApp;
}
if (actionCodeSettings.url) {
firActionCodeSettings.URL = NSURL.URLWithString(actionCodeSettings.url);
}
if (actionCodeSettings.iOS) {
if (actionCodeSettings.iOS.bundleId) {
firActionCodeSettings.setIOSBundleID(actionCodeSettings.iOS.bundleId);
}
if (actionCodeSettings.iOS.dynamicLinkDomain) {
firActionCodeSettings.dynamicLinkDomain = actionCodeSettings.iOS.dynamicLinkDomain;
}
}
if (actionCodeSettings.android && actionCodeSettings.android.packageName) {
firActionCodeSettings.setAndroidPackageNameInstallIfNotAvailableMinimumVersion(actionCodeSettings.android.packageName, actionCodeSettings.android.installApp, actionCodeSettings.android.minimumVersion || null);
}
user.sendEmailVerificationWithActionCodeSettingsCompletion(firActionCodeSettings, onCompletion);
} else {
user.sendEmailVerificationWithCompletion(onCompletion);
}
} else {
reject('Log in first');
}
} catch (ex) {
console.log('Error in firebase.sendEmailVerification: ' + ex);
reject(ex);
}
});
};
firebase.logout = (arg) => {
return new Promise((resolve, reject) => {
try {
FIRAuth.auth().signOut();
firebase.currentAdditionalUserInfo = null;
if (typeof GIDSignIn !== 'undefined') {
GIDSignIn.sharedInstance().disconnect();
}
if (typeof FBSDKLoginManager !== 'undefined') {
FBSDKLoginManager.alloc().logOut();
}
resolve();
} catch (ex) {
console.log('Error in firebase.logout: ' + ex);
reject(ex);
}
});
};
firebase.unlink = (providerId) => {
return new Promise((resolve, reject) => {
try {
const user = FIRAuth.auth().currentUser;
if (!user) {
reject('Not logged in');
return;
}
user.unlinkFromProviderCompletion(providerId, (user, error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve(user);
}
});
} catch (ex) {
console.log('Error in firebase.logout: ' + ex);
reject(ex);
}
});
};
function toLoginResult(user, additionalUserInfo) {
if (!user) {
return null;
}
if (additionalUserInfo) {
firebase.currentAdditionalUserInfo = additionalUserInfo;
}
const providers = [];
if (user.providerData) {
for (let i = 0, l = user.providerData.count; i < l; i++) {
const firUserInfo = user.providerData.objectAtIndex(i);
const pid = firUserInfo.valueForKey('providerID');
if (pid === 'facebook.com' && typeof FBSDKAccessToken !== 'undefined') {
providers.push({ id: pid, token: FBSDKAccessToken.currentAccessToken ? FBSDKAccessToken.currentAccessToken.tokenString : null });
} else if (pid === 'google.com' && typeof GIDSignIn !== 'undefined' && GIDSignIn.sharedInstance() && GIDSignIn.sharedInstance().currentUser) {
const gidCurrentIdToken = GIDSignIn.sharedInstance().currentUser.authentication.accessToken;
providers.push({ id: pid, token: gidCurrentIdToken });
} else if (pid === 'apple.com') {
} else {
providers.push({ id: pid });
}
}
}
const loginResult = {
uid: user.uid,
anonymous: user.anonymous,
isAnonymous: user.anonymous,
providers: providers,
photoURL: user.photoURL ? user.photoURL.absoluteString : null,
email: user.email,
emailVerified: user.emailVerified,
displayName: user.displayName,
phoneNumber: user.phoneNumber,
refreshToken: user.refreshToken,
metadata: {
creationTimestamp: user.metadata.creationDate,
lastSignInTimestamp: user.metadata.lastSignInDate,
},
getIdToken: (forceRefresh) =>
new Promise((resolve, reject) => {
firebase
.getAuthToken({ forceRefresh })
.then((result) => resolve(result.token))
.catch(reject);
}),
getIdTokenResult: (forceRefresh) =>
new Promise((resolve, reject) => {
firebase
.getAuthToken({ forceRefresh })
.then((result) => resolve(result))
.catch(reject);
}),
sendEmailVerification: (actionCodeSettings) => firebase.sendEmailVerification(actionCodeSettings),
};
if (firebase.currentAdditionalUserInfo) {
loginResult.additionalUserInfo = {
providerId: firebase.currentAdditionalUserInfo.providerID,
username: firebase.currentAdditionalUserInfo.username,
isNewUser: firebase.currentAdditionalUserInfo.newUser,
profile: firebaseUtils.toJsObject(firebase.currentAdditionalUserInfo.profile),
};
}
return loginResult;
}
firebase.getAuthToken = (arg) => {
return new Promise((resolve, reject) => {
try {
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
const user = fAuth.currentUser;
if (user) {
user.getIDTokenResultForcingRefreshCompletion(arg.forceRefresh, (result, error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve({
token: result.token,
claims: firebaseUtils.toJsObject(result.claims),
signInProvider: result.signInProvider,
expirationTime: firebaseUtils.toJsObject(result.expirationDate),
issuedAtTime: firebaseUtils.toJsObject(result.issuedAtDate),
authTime: firebaseUtils.toJsObject(result.authDate),
});
}
});
} else {
reject('Log in first');
}
} catch (ex) {
console.log('Error in firebase.getAuthToken: ' + ex);
reject(ex);
}
});
};
firebase.login = (arg) => {
return new Promise((resolve, reject) => {
try {
const onCompletionWithAuthResult = (authResult, error) => {
if (error) {
if (typeof GIDSignIn !== 'undefined') {
GIDSignIn.sharedInstance().disconnect();
}
reject(error.localizedDescription);
} else {
resolve(toLoginResult(authResult && authResult.user, authResult && authResult.additionalUserInfo));
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(authResult.user),
});
}
};
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
firebase.moveLoginOptionsToObjects(arg);
if (arg.type === firebase.LoginType.ANONYMOUS) {
fAuth.signInAnonymouslyWithCompletion(onCompletionWithAuthResult);
} else if (arg.type === firebase.LoginType.PASSWORD) {
if (!arg.passwordOptions || !arg.passwordOptions.email || !arg.passwordOptions.password) {
reject("Auth type PASSWORD requires an 'passwordOptions.email' and 'passwordOptions.password' argument");
return;
}
const fIRAuthCredential = FIREmailAuthProvider.credentialWithEmailPassword(arg.passwordOptions.email, arg.passwordOptions.password);
if (fAuth.currentUser) {
const onCompletionLink = (authData, error) => {
if (error) {
log('--- linking error: ' + error.localizedDescription);
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
} else {
onCompletionWithAuthResult(authData, error);
}
};
fAuth.currentUser.linkWithCredentialCompletion(fIRAuthCredential, onCompletionLink);
} else {
fAuth.signInWithEmailPasswordCompletion(arg.passwordOptions.email, arg.passwordOptions.password, onCompletionWithAuthResult);
}
} else if (arg.type === firebase.LoginType.EMAIL_LINK) {
if (!arg.emailLinkOptions || !arg.emailLinkOptions.email) {
reject("Auth type EMAIL_LINK requires an 'emailLinkOptions.email' argument");
return;
}
if (!arg.emailLinkOptions.url) {
reject("Auth type EMAIL_LINK requires an 'emailLinkOptions.url' argument");
return;
}
const firActionCodeSettings = FIRActionCodeSettings.new();
firActionCodeSettings.URL = NSURL.URLWithString(arg.emailLinkOptions.url);
firActionCodeSettings.handleCodeInApp = true;
firActionCodeSettings.setIOSBundleID(arg.emailLinkOptions.iOS ? arg.emailLinkOptions.iOS.bundleId : NSBundle.mainBundle.bundleIdentifier);
firActionCodeSettings.setAndroidPackageNameInstallIfNotAvailableMinimumVersion(arg.emailLinkOptions.android ? arg.emailLinkOptions.android.packageName : NSBundle.mainBundle.bundleIdentifier, arg.emailLinkOptions.android ? arg.emailLinkOptions.android.installApp || false : false, arg.emailLinkOptions.android ? arg.emailLinkOptions.android.minimumVersion || '1' : '1');
fAuth.sendSignInLinkToEmailActionCodeSettingsCompletion(arg.emailLinkOptions.email, firActionCodeSettings, (error) => {
if (error) {
reject(error.localizedDescription);
return;
}
firebase.rememberEmailForEmailLinkLogin(arg.emailLinkOptions.email);
resolve();
});
} else if (arg.type === firebase.LoginType.PHONE) {
if (!arg.phoneOptions || !arg.phoneOptions.phoneNumber) {
reject("Auth type PHONE requires a 'phoneOptions.phoneNumber' argument");
return;
}
FIRPhoneAuthProvider.provider().verifyPhoneNumberUIDelegateCompletion(arg.phoneOptions.phoneNumber, null, (verificationID, error) => {
if (error) {
reject(error.localizedDescription);
return;
}
firebase.requestPhoneAuthVerificationCode((userResponse) => {
if (userResponse === undefined) {
reject('Prompt was canceled');
return;
}
const fIRAuthCredential = FIRPhoneAuthProvider.provider().credentialWithVerificationIDVerificationCode(verificationID, userResponse);
if (fAuth.currentUser) {
const onCompletionLink = (authData, error) => {
if (error) {
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
} else {
onCompletionWithAuthResult(authData, error);
}
};
fAuth.currentUser.linkWithCredentialCompletion(fIRAuthCredential, onCompletionLink);
} else {
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
}
}, arg.phoneOptions.verificationPrompt);
});
} else if (arg.type === firebase.LoginType.CUSTOM) {
if (!arg.customOptions || (!arg.customOptions.token && !arg.customOptions.tokenProviderFn)) {
reject("Auth type CUSTOM requires a 'customOptions.token' or 'customOptions.tokenProviderFn' argument");
return;
}
if (arg.customOptions.token) {
fAuth.signInWithCustomTokenCompletion(arg.customOptions.token, onCompletionWithAuthResult);
} else if (arg.customOptions.tokenProviderFn) {
arg.customOptions.tokenProviderFn().then(
(token) => {
fAuth.signInWithCustomTokenCompletion(token, onCompletionWithAuthResult);
},
(error) => {
reject(error);
}
);
}
} else if (arg.type === firebase.LoginType.FACEBOOK) {
if (typeof FBSDKLoginManager === 'undefined') {
reject('Facebook SDK not installed - see Podfile');
return;
}
const onFacebookCompletion = (fbSDKLoginManagerLoginResult, error) => {
if (error) {
console.log('Facebook login error ' + error);
reject(error.localizedDescription);
} else if (fbSDKLoginManagerLoginResult.isCancelled) {
reject('login cancelled');
} else {
const fIRAuthCredential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken.tokenString);
if (fAuth.currentUser) {
const onCompletionLink = (authData, error) => {
if (error) {
log('--- linking error: ' + error.localizedDescription);
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
} else {
onCompletionWithAuthResult(authData);
}
};
fAuth.currentUser.linkWithCredentialCompletion(fIRAuthCredential, onCompletionLink);
} else {
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
}
}
};
const fbSDKLoginManager = FBSDKLoginManager.new();
let scopes = ['public_profile', 'email'];
if (arg.facebookOptions && arg.facebookOptions.scopes) {
scopes = arg.facebookOptions.scopes;
}
fbSDKLoginManager.logInWithPermissionsFromViewControllerHandler(scopes, null, onFacebookCompletion);
} else if (arg.type === firebase.LoginType.APPLE) {
if (parseInt(Device.osVersion) < 13) {
reject("Sign in with Apple requires iOS 13 or higher. You're running iOS " + Device.osVersion);
return;
}
firebase._currentNonce = getNonce(32);
const sha256Nonce = Sha256(firebase._currentNonce);
const appleIDProvider = ASAuthorizationAppleIDProvider.new();
const appleIDRequest = appleIDProvider.createRequest();
let scopes = [ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
if (arg.appleOptions && arg.appleOptions.scopes) {
scopes = [];
arg.appleOptions.scopes.forEach((scope) => {
if (scope === 'name') {
scopes.push(ASAuthorizationScopeFullName);
} else if (scope === 'email') {
scopes.push(ASAuthorizationScopeEmail);
} else {
console.log('Unknown scope: ' + scope);
}
});
}
appleIDRequest.requestedScopes = scopes;
appleIDRequest.nonce = sha256Nonce;
const authorizationController = ASAuthorizationController.alloc().initWithAuthorizationRequests([appleIDRequest]);
const delegate = ASAuthorizationControllerDelegateImpl.createWithOwnerAndResolveReject(new WeakRef(this), resolve, reject);
CFRetain(delegate);
authorizationController.delegate = delegate;
authorizationController.presentationContextProvider = ASAuthorizationControllerPresentationContextProvidingImpl.createWithOwnerAndCallback(new WeakRef(this));
authorizationController.performRequests();
} else if (arg.type === firebase.LoginType.GOOGLE) {
if (typeof GIDSignIn === 'undefined') {
reject('Google Sign In not installed - see Podfile');
return;
}
const sIn = GIDSignIn.sharedInstance();
sIn.presentingViewController = arg.ios && arg.ios.controller ? arg.ios.controller : Application.ios.rootController;
sIn.clientID = FIRApp.defaultApp().options.clientID;
if (arg.googleOptions && arg.googleOptions.hostedDomain) {
sIn.hostedDomain = arg.googleOptions.hostedDomain;
}
if (arg.googleOptions && arg.googleOptions.scopes) {
sIn.scopes = arg.googleOptions.scopes;
}
let delegate = GIDSignInDelegateImpl.new().initWithCallback((user, error) => {
if (error === null) {
firebase._gIDAuthentication = user.authentication;
const fIRAuthCredential = FIRGoogleAuthProvider.credentialWithIDTokenAccessToken(firebase._gIDAuthentication.idToken, firebase._gIDAuthentication.accessToken);
if (fAuth.currentUser) {
const onCompletionLink = (user, error) => {
if (error) {
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
} else {
onCompletionWithAuthResult(user);
}
};
fAuth.currentUser.linkWithCredentialCompletion(fIRAuthCredential, onCompletionLink);
} else {
fAuth.signInWithCredentialCompletion(fIRAuthCredential, onCompletionWithAuthResult);
}
} else {
reject(error.localizedDescription);
}
CFRelease(delegate);
delegate = undefined;
});
CFRetain(delegate);
sIn.delegate = delegate;
sIn.signIn();
} else {
reject('Unsupported auth type: ' + arg.type);
}
} catch (ex) {
console.log('Error in firebase.login: ' + ex);
reject(ex);
}
});
};
firebase.reauthenticate = (arg) => {
return new Promise((resolve, reject) => {
try {
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
const user = fAuth.currentUser;
if (user === null) {
reject('no current user');
return;
}
firebase.moveLoginOptionsToObjects(arg);
let authCredential = null;
if (arg.type === firebase.LoginType.PASSWORD) {
if (!arg.passwordOptions || !arg.passwordOptions.email || !arg.passwordOptions.password) {
reject("Auth type PASSWORD requires an 'passwordOptions.email' and 'passwordOptions.password' argument");
return;
}
authCredential = FIREmailAuthProvider.credentialWithEmailPassword(arg.passwordOptions.email, arg.passwordOptions.password);
} else if (arg.type === firebase.LoginType.GOOGLE) {
if (!firebase._gIDAuthentication) {
reject('Not currently logged in with Google');
return;
}
authCredential = FIRGoogleAuthProvider.credentialWithIDTokenAccessToken(firebase._gIDAuthentication.idToken, firebase._gIDAuthentication.accessToken);
} else if (arg.type === firebase.LoginType.FACEBOOK) {
if (!FBSDKAccessToken.currentAccessToken) {
reject('Not currently logged in with Facebook');
return;
}
authCredential = FIRFacebookAuthProvider.credentialWithAccessToken(FBSDKAccessToken.currentAccessToken.tokenString);
}
if (authCredential === null) {
reject('arg.type should be one of LoginType.PASSWORD | LoginType.GOOGLE | LoginType.FACEBOOK');
return;
}
const onCompletion = (authResult, error) => {
if (error) {
reject(error.localizedDescription);
} else {
firebase.notifyAuthStateListeners({
loggedIn: true,
user: toLoginResult(authResult.user),
});
resolve(toLoginResult(authResult && authResult.user, authResult && authResult.additionalUserInfo));
}
};
user.reauthenticateWithCredentialCompletion(authCredential, onCompletion);
} catch (ex) {
console.log('Error in firebase.reauthenticate: ' + ex);
reject(ex);
}
});
};
firebase.reloadUser = () => {
return new Promise((resolve, reject) => {
try {
const user = FIRAuth.auth().currentUser;
if (user === null) {
reject('no current user');
return;
}
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
user.reloadWithCompletion(onCompletion);
} catch (ex) {
console.log('Error in firebase.reloadUser: ' + ex);
reject(ex);
}
});
};
firebase.sendPasswordResetEmail = (email) => {
return new Promise((resolve, reject) => {
try {
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
FIRAuth.auth().sendPasswordResetWithEmailCompletion(email, onCompletion);
} catch (ex) {
console.log('Error in firebase.sendPasswordResetEmail: ' + ex);
reject(ex);
}
});
};
firebase.updateEmail = (newEmail) => {
return new Promise((resolve, reject) => {
try {
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
const user = FIRAuth.auth().currentUser;
if (user === null) {
reject('no current user');
} else {
user.updateEmailCompletion(newEmail, onCompletion);
}
} catch (ex) {
console.log('Error in firebase.updateEmail: ' + ex);
reject(ex);
}
});
};
firebase.updatePassword = (newPassword) => {
return new Promise((resolve, reject) => {
try {
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
const user = FIRAuth.auth().currentUser;
if (user === null) {
reject('no current user');
} else {
user.updatePasswordCompletion(newPassword, onCompletion);
}
} catch (ex) {
console.log('Error in firebase.updatePassword: ' + ex);
reject(ex);
}
});
};
firebase.createUser = (arg) => {
return new Promise((resolve, reject) => {
try {
const onCompletion = (authResult, error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve(toLoginResult(authResult.user, authResult.additionalUserInfo));
}
};
if (!arg.email || !arg.password) {
reject('Creating a user requires an email and password argument');
} else {
FIRAuth.auth().createUserWithEmailPasswordCompletion(arg.email, arg.password, onCompletion);
}
} catch (ex) {
console.log('Error in firebase.createUser: ' + ex);
reject(ex);
}
});
};
firebase.deleteUser = (arg) => {
return new Promise((resolve, reject) => {
try {
const user = FIRAuth.auth().currentUser;
if (user === null) {
reject('no current user');
return;
}
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
user.deleteWithCompletion(onCompletion);
} catch (ex) {
console.log('Error in firebase.deleteUser: ' + ex);
reject(ex);
}
});
};
firebase.updateProfile = (arg) => {
return new Promise((resolve, reject) => {
try {
const onCompletion = (error) => {
if (error) {
reject(error.localizedDescription);
} else {
resolve();
}
};
const fAuth = FIRAuth.auth();
if (fAuth === null) {
reject('Run init() first!');
return;
}
if (!arg.displayName && !arg.photoURL) {
reject('Updating a profile requires a displayName and / or a photoURL argument');
} else {
const user = fAuth.currentUser;
if (user) {
const changeRequest = user.profileChangeRequest();
changeRequest.displayName = arg.displayName;
changeRequest.photoURL = NSURL.URLWithString(arg.photoURL);
changeRequest.commitChangesWithCompletion(onCompletion);
} else {
reject();
}
}
} catch (ex) {
console.log('Error in firebase.updateProfile: ' + ex);
reject(ex);
}
});
};
firebase._addObservers = (to, updateCallback) => {
const listeners = [];
listeners.push(
to.observeEventTypeWithBlock(0, (snapshot) => {
updateCallback(firebase.getCallbackData('ChildAdded', snapshot));
})
);
listeners.push(
to.observeEventTypeWithBlock(1, (snapshot) => {
updateCallback(firebase.getCallbackData('ChildRemoved', snapshot));
})
);
listeners.push(
to.observeEventTypeWithBlock(2, (snapshot) => {
updateCallback(firebase.getCallbackData('ChildChanged', snapshot));
})
);
listeners.push(
to.observeEventTypeWithBlock(3, (snapshot) => {
updateCallback(firebase.getCallbackData('ChildMoved', snapshot));
})
);
return listeners;
};
firebase.keepInSync = (path, switchOn) => {
return new Promise((resolve, reject) => {
try {
const where = FIRDatabase.database().reference().child(path);
where.keepSynced(switchOn);
resolve();
} catch (ex) {
console.log('Error in firebase.keepInSync: ' + ex);
reject(ex);
}
});
};
firebase.addChildEventListener = (updateCallback, path) => {
return new Promise((resolve, reject) => {
try {
const where = path === undefined ? FIRDatabase.database().reference() : FIRDatabase.database().reference().child(path);
resolve({
path: path,
listeners: firebase._addObservers(where, updateCallback),
});
} catch (ex) {
console.log('Error in firebase.addChildEventListener: ' + ex);
reject(ex);
}
});
};
firebase.addValueEventListener = (updateCallback, path) => {
return new Promise((resolve, reject) => {
try {
const where = path === undefined ? FIRDatabase.database().reference() : FIRDatabase.database().reference().child(path);
const listener = where.observeEventTypeWithBlockWithCancelBlock(
4,
(snapshot) => {
updateCallback(firebase.getCallbackData('ValueChanged', snapshot));
},
(firebaseError) => {
updateCallback({
error: firebaseError.localizedDescription,
});
}
);
resolve({
path: path,
listeners: [listener],
});
} catch (ex) {
console.log('Error in firebase.addChildEventListener: ' + ex);
reject(ex);
}
});
};
firebase.getValue = (path) => {
return new Promise((resolve, reject) => {
try {
const where = path === undefined ? FIRDatabase.database().reference() : FIRDatabase.database().reference().child(path);
where.observeSingleEventOfTypeWithBlockWithCancelBlock(
4,
(snapshot) => {
resolve(firebase.getCallbackData('ValueChanged', snapshot));
},
(firebaseError) => {
reject(firebaseError.localizedDescription);
}
);
} catch (ex) {
console.log('Error in firebase.getValue: ' + ex);
reject(ex);
}
});
};
firebase.removeEventListeners = (listeners, path) => {
return new Promise((resolve, reject) => {
try {
const where = path === undefined ? FIRDatabase.database().reference() : FIRDatabase.database().reference().child(path);
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
where.removeObserverWithHandle(listener);
}
resolve();
} catch (ex) {
console.log('Error in firebase.removeEventListeners: ' + ex);
reject(ex);
}
});
};
firebase.push = (path, val) => {
return new Promise((resolve, reject) => {
try {
const ref = FIRDatabase.database().reference().child(path).childByAutoId();
ref.setValueWithCompletionBlock(val, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve({ key: ref.key });
});
} catch (ex) {
console.log('Error in firebase.push: ' + ex);
reject(ex);
}
});
};
firebase.setValue = (path, val) => {
return new Promise((resolve, reject) => {
try {
FIRDatabase.database()
.reference()
.child(path)
.setValueWithCompletionBlock(val, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.setValue: ' + ex);
reject(ex);
}
});
};
firebase.update = (path, val) => {
return new Promise((resolve, reject) => {
try {
if (typeof val === 'object') {
FIRDatabase.database()
.reference()
.child(path)
.updateChildValuesWithCompletionBlock(val, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} else {
const lastPartOfPath = path.lastIndexOf('/');
const pathPrefix = path.substring(0, lastPartOfPath);
const pathSuffix = path.substring(lastPartOfPath + 1);
const updateObject = '{"' + pathSuffix + '" : "' + val + '"}';
FIRDatabase.database()
.reference()
.child(pathPrefix)
.updateChildValuesWithCompletionBlock(JSON.parse(updateObject), (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
}
} catch (ex) {
console.log('Error in firebase.update: ' + ex);
reject(ex);
}
});
};
firebase.query = (updateCallback, path, options) => {
return new Promise((resolve, reject) => {
try {
const where = path === undefined ? FIRDatabase.database().reference() : FIRDatabase.database().reference().child(path);
let query;
if (options.orderBy.type === firebase.QueryOrderByType.KEY) {
query = where.queryOrderedByKey();
} else if (options.orderBy.type === firebase.QueryOrderByType.VALUE) {
query = where.queryOrderedByValue();
} else if (options.orderBy.type === firebase.QueryOrderByType.PRIORITY) {
query = where.queryOrderedByPriority();
} else if (options.orderBy.type === firebase.QueryOrderByType.CHILD) {
if (options.orderBy.value === undefined || options.orderBy.value === null) {
reject("When orderBy.type is 'child' you must set orderBy.value as well.");
return;
}
query = where.queryOrderedByChild(options.orderBy.value);
} else {
reject('Invalid orderBy.type, use constants like firebase.QueryOrderByType.VALUE');
return;
}
if (options.range && options.range.type) {
if (options.range.type === firebase.QueryRangeType.START_AT) {
query = query.queryStartingAtValue(options.range.value);
} else if (options.range.type === firebase.QueryRangeType.END_AT) {
query = query.queryEndingAtValue(options.range.value);
} else if (options.range.type === firebase.QueryRangeType.EQUAL_TO) {
query = query.queryEqualToValue(options.range.value);
} else {
reject('Invalid range.type, use constants like firebase.QueryRangeType.START_AT');
return;
}
}
if (options.ranges) {
for (let i = 0; i < options.ranges.length; i++) {
const range = options.ranges[i];
if (range.value === undefined || range.value === null) {
reject('Please set ranges[' + i + '].value');
return;
}
if (range.type === firebase.QueryRangeType.START_AT) {
query = query.queryStartingAtValue(range.value);
} else if (range.type === firebase.QueryRangeType.END_AT) {
query = query.queryEndingAtValue(range.value);
} else if (range.type === firebase.QueryRangeType.EQUAL_TO) {
query = query.queryEqualToValue(range.value);
} else {
reject('Invalid ranges[' + i + '].type, use constants like firebase.QueryRangeType.START_AT');
return;
}
}
}
if (options.limit && options.limit.type) {
if (options.limit.value === undefined || options.limit.value === null) {
reject('Please set limit.value');
return;
}
if (options.limit.type === firebase.QueryLimitType.FIRST) {
query = query.queryLimitedToFirst(options.limit.value);
} else if (options.limit.type === firebase.QueryLimitType.LAST) {
query = query.queryLimitedToLast(options.limit.value);
} else {
reject('Invalid limit.type, use constants like firebase.queryOptions.limitType.FIRST');
return;
}
}
if (options.singleEvent) {
query.observeSingleEventOfTypeWithBlock(4, (snapshot) => {
const result = {
type: 'ValueChanged',
key: snapshot.key,
value: {},
children: [],
};
for (let i = 0; i < snapshot.children.allObjects.count; i++) {
const snap = snapshot.children.allObjects.objectAtIndex(i);
const val = firebaseUtils.toJsObject(snap.value);
result.value[snap.key] = val;
result.children.push(val);
}
if (updateCallback) updateCallback(result);
resolve(result);
});
} else {
resolve({
path: path,
listeners: firebase._addObservers(query, updateCallback),
});
}
} catch (ex) {
console.log('Error in firebase.query: ' + ex);
reject(ex);
}
});
};
firebase.remove = (path) => {
return new Promise((resolve, reject) => {
try {
FIRDatabase.database()
.reference()
.child(path)
.setValueWithCompletionBlock(null, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.remove: ' + ex);
reject(ex);
}
});
};
class OnDisconnect {
constructor(dbRef, path) {
this.dbRef = dbRef;
this.path = path;
}
cancel() {
return new Promise((resolve, reject) => {
try {
this.dbRef.cancelDisconnectOperationsWithCompletionBlock((error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.onDisconnect.cancel: ' + ex);
reject(ex);
}
});
}
remove() {
return new Promise((resolve, reject) => {
try {
this.dbRef.onDisconnectRemoveValueWithCompletionBlock((error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.onDisconnect.remove: ' + ex);
reject(ex);
}
});
}
set(value) {
return new Promise((resolve, reject) => {
try {
this.dbRef.onDisconnectSetValueWithCompletionBlock(value, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.onDisconnect.set: ' + ex);
reject(ex);
}
});
}
setWithPriority(value, priority) {
return new Promise((resolve, reject) => {
try {
this.dbRef.onDisconnectSetValueAndPriorityWithCompletionBlock(value, priority, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} catch (ex) {
console.log('Error in firebase.onDisconnect.setWithPriority: ' + ex);
reject(ex);
}
});
}
update(values) {
return new Promise((resolve, reject) => {
try {
if (typeof values === 'object') {
this.dbRef.onDisconnectUpdateChildValuesWithCompletionBlock(values, (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
} else {
const lastPartOfPath = this.path.lastIndexOf('/');
const pathPrefix = this.path.substring(0, lastPartOfPath);
const pathSuffix = this.path.substring(lastPartOfPath + 1);
const updateObject = '{"' + pathSuffix + '" : "' + values + '"}';
FIRDatabase.database()
.reference()
.child(pathPrefix)
.updateChildValuesWithCompletionBlock(JSON.parse(updateObject), (error, dbRef) => {
error ? reject(error.localizedDescription) : resolve();
});
}
} catch (ex) {
console.log('Error in firebase.onDisconnect.update: ' + ex);
reject(ex);
}
});
}
}
firebase.onDisconnect = (path) => {
if (!firebase.initialized) {
console.error('Please run firebase.init() before firebase.onDisconnect()');
throw new Error('FirebaseApp is not initialized. Make sure you run firebase.init() first');
}
const dbRef = FIRDatabase.database().reference().child(path);
return new OnDisconnect(dbRef, path);
};
firebase.transaction = (path, transactionUpdate, onComplete) => {
return new Promise((resolve, reject) => {
if (!firebase.initialized) {
console.error('Please run firebase.init() before firebase.transaction()');
throw new Error('FirebaseApp is not initialized. Make sure you run firebase.init() first');
}
const dbRef = FIRDatabase.database().reference().child(path);
dbRef.runTransactionBlockAndCompletionBlock(
(mutableData) => {
const desiredValue = transactionUpdate(firebaseUtils.toJs