Skip to content
Merged
11 changes: 11 additions & 0 deletions packages/app/lib/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,14 @@ export function tryJSONStringify(data) {
return null;
}
}

export const MODULAR_DEPRECATION_ARG = 'react-native-firebase-modular-method-call';

export function isNotModularCall(args) {
for (let i = 0; i < args.length; i++) {
if (args[i] === MODULAR_DEPRECATION_ARG) {
return false;
}
}
return true;
}
213 changes: 212 additions & 1 deletion packages/crashlytics/__tests__/crashlytics.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it } from '@jest/globals';
import { describe, expect, it, jest } from '@jest/globals';

import {
firebase,
Expand Down Expand Up @@ -79,4 +79,215 @@ describe('Crashlytics', function () {
expect(setCrashlyticsCollectionEnabled).toBeDefined();
});
});

describe('test `console.warn` is called for RNFB v8 API & not called for v9 API', function () {
it('checkForUnsentReports', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { checkForUnsentReports: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

checkForUnsentReports(crashlytics);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.checkForUnsentReports();
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('crash', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { crash: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

crash(crashlytics);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.crash();
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('deleteUnsentReports', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { deleteUnsentReports: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

deleteUnsentReports(crashlytics);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.deleteUnsentReports();
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('didCrashOnPreviousExecution', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { didCrashOnPreviousExecution: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

didCrashOnPreviousExecution(crashlytics);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.didCrashOnPreviousExecution();
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('log', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { log: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

log(crashlytics, 'message');
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.log('message');
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('setAttribute', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { setAttribute: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

setAttribute(crashlytics, 'name', 'value');
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.setAttribute('name', 'value');
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('setAttributes', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { setAttributes: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

setAttributes(crashlytics, {});
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.setAttributes({});
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('setUserId', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { setUserId: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

setUserId(crashlytics, 'id');
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.setUserId('id');
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('recordError', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { recordError: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

recordError(crashlytics, new Error(), 'name');
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.recordError(new Error(), 'name');
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('sendUnsentReports', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { sendUnsentReports: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

sendUnsentReports(crashlytics);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.sendUnsentReports();
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});

it('setCrashlyticsCollectionEnabled', function () {
const crashlytics = getCrashlytics();
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
// @ts-ignore test
const nativeMock = { setCrashlyticsCollectionEnabled: jest.fn() };
// @ts-ignore test
jest.spyOn(crashlytics, 'native', 'get').mockReturnValue(nativeMock);

setCrashlyticsCollectionEnabled(crashlytics, true);
// Check that console.warn was not called for v9 method call
expect(consoleWarnSpy).not.toHaveBeenCalled();

crashlytics.setCrashlyticsCollectionEnabled(true);
// Check that console.warn was called for v8 method call
expect(consoleWarnSpy).toHaveBeenCalled();
// Restore the original console.warn
consoleWarnSpy.mockRestore();
});
});
});
68 changes: 68 additions & 0 deletions packages/crashlytics/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
isObject,
isString,
isOther,
isNotModularCall,
} from '@react-native-firebase/app/lib/common';
import {
createModuleNamespace,
Expand Down Expand Up @@ -51,10 +52,17 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

get isCrashlyticsCollectionEnabled() {
// Purposefully did not deprecate this as I think it should remain a property rather than a method.
return this._isCrashlyticsCollectionEnabled;
}

checkForUnsentReports() {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `checkForUnsentReports()` instead.',
);
}
if (this.isCrashlyticsCollectionEnabled) {
throw new Error(
"firebase.crashlytics().setCrashlyticsCollectionEnabled(*) has been set to 'true', all reports are automatically sent.",
Expand All @@ -64,22 +72,52 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

crash() {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `crash()` instead.',
);
}
this.native.crash();
}

async deleteUnsentReports() {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `deleteUnsentReports()` instead.',
);
}
await this.native.deleteUnsentReports();
}

didCrashOnPreviousExecution() {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `didCrashOnPreviousExecution()` instead.',
);
}
return this.native.didCrashOnPreviousExecution();
}

log(message) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `log()` instead.',
);
}
this.native.log(`${message}`);
}

setAttribute(name, value) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `log()` instead.',
);
}
if (!isString(name)) {
throw new Error(
'firebase.crashlytics().setAttribute(*, _): The supplied property name must be a string.',
Expand All @@ -96,6 +134,12 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

setAttributes(object) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `setAttributes()` instead.',
);
}
if (!isObject(object)) {
throw new Error(
'firebase.crashlytics().setAttributes(*): The supplied arg must be an object of key value strings.',
Expand All @@ -106,6 +150,12 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

setUserId(userId) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `setUserId()` instead.',
);
}
if (!isString(userId)) {
throw new Error(
'firebase.crashlytics().setUserId(*): The supplied userId must be a string value.',
Expand All @@ -116,6 +166,12 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

recordError(error, jsErrorName) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `recordError()` instead.',
);
}
if (isError(error)) {
StackTrace.fromError(error, { offline: true }).then(stackFrames => {
this.native.recordError(createNativeErrorObj(error, stackFrames, false, jsErrorName));
Expand All @@ -128,12 +184,24 @@ class FirebaseCrashlyticsModule extends FirebaseModule {
}

sendUnsentReports() {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `sendUnsentReports()` instead.',
);
}
if (this.isCrashlyticsCollectionEnabled) {
this.native.sendUnsentReports();
}
}

setCrashlyticsCollectionEnabled(enabled) {
if (isNotModularCall(arguments)) {
// eslint-disable-next-line no-console
console.warn(
'This v8 method is deprecated and will be removed in the next major release as part of move to match Firebase Web modular v9 SDK API. Please use `setCrashlyticsCollectionEnabled()` instead.',
);
}
if (!isBoolean(enabled)) {
throw new Error(
"firebase.crashlytics().setCrashlyticsCollectionEnabled(*) 'enabled' must be a boolean.",
Expand Down
Loading
Loading