diff --git a/.changeset/chilly-seahorses-design.md b/.changeset/chilly-seahorses-design.md new file mode 100644 index 00000000..d0dcc3f3 --- /dev/null +++ b/.changeset/chilly-seahorses-design.md @@ -0,0 +1,5 @@ +--- +'@capacitor-firebase/performance': minor +--- + +feat: add `putAttribute(...)`, `getAttribute(...)`, `getAttributes(...)`, `putMetric(...)`, `getMetric(...)` and `record(...)` methods diff --git a/packages/performance/README.md b/packages/performance/README.md index b499547c..8a026890 100644 --- a/packages/performance/README.md +++ b/packages/performance/README.md @@ -69,7 +69,15 @@ const isEnabled = async () => { * [`incrementMetric(...)`](#incrementmetric) * [`setEnabled(...)`](#setenabled) * [`isEnabled()`](#isenabled) +* [`putAttribute(...)`](#putattribute) +* [`getAttribute(...)`](#getattribute) +* [`getAttributes(...)`](#getattributes) +* [`removeAttribute(...)`](#removeattribute) +* [`putMetric(...)`](#putmetric) +* [`getMetric(...)`](#getmetric) +* [`record(...)`](#record) * [Interfaces](#interfaces) +* [Type Aliases](#type-aliases) @@ -160,6 +168,132 @@ Determines whether performance monitoring is enabled or disabled. -------------------- +### putAttribute(...) + +```typescript +putAttribute(options: PutAttributeOptions) => Promise +``` + +Sets a custom attribute of a trace to a given value. + +| Param | Type | +| ------------- | ------------------------------------------------------------------- | +| **`options`** | PutAttributeOptions | + +**Since:** 6.3.0 + +-------------------- + + +### getAttribute(...) + +```typescript +getAttribute(options: GetAttributeOptions) => Promise +``` + +Returns the value of a custom attribute of a trace. + +| Param | Type | +| ------------- | ------------------------------------------------------------------- | +| **`options`** | GetAttributeOptions | + +**Returns:** Promise<GetAttributeResult> + +**Since:** 6.3.0 + +-------------------- + + +### getAttributes(...) + +```typescript +getAttributes(options: GetAttributesOptions) => Promise +``` + +Gets the all the custom attributes of a trace with their values. + +| Param | Type | +| ------------- | --------------------------------------------------------------------- | +| **`options`** | GetAttributesOptions | + +**Returns:** Promise<GetAttributesResult> + +**Since:** 6.3.0 + +-------------------- + + +### removeAttribute(...) + +```typescript +removeAttribute(options: RemoveAttributeOptions) => Promise +``` + +Removes a custom attribute from a trace given its name. + +| Param | Type | +| ------------- | ------------------------------------------------------------------- | +| **`options`** | GetAttributeOptions | + +**Since:** 6.3.0 + +-------------------- + + +### putMetric(...) + +```typescript +putMetric(options: PutMetricOptions) => Promise +``` + +Sets the value of a custom metric. + +| Param | Type | +| ------------- | ------------------------------------------------------------- | +| **`options`** | PutMetricOptions | + +**Since:** 6.3.0 + +-------------------- + + +### getMetric(...) + +```typescript +getMetric(options: GetMetricOptions) => Promise +``` + +Get the value of a custom metric by name. + +| Param | Type | +| ------------- | ------------------------------------------------------------- | +| **`options`** | GetMetricOptions | + +**Returns:** Promise<GetMetricResult> + +**Since:** 6.3.0 + +-------------------- + + +### record(...) + +```typescript +record(options: RecordOptions) => Promise +``` + +Records a trace given its name and options. +Only available on web. + +| Param | Type | +| ------------- | ------------------------------------------------------- | +| **`options`** | RecordOptions | + +**Since:** 6.3.0 + +-------------------- + + ### Interfaces @@ -199,6 +333,86 @@ Determines whether performance monitoring is enabled or disabled. | ------------- | -------------------- | --------------------------------------------------------------- | ----- | | **`enabled`** | boolean | `true` if performance monitoring is enabled, otherwise `false`. | 0.1.0 | + +#### PutAttributeOptions + +| Prop | Type | Description | Since | +| --------------- | ------------------- | --------------------------------------- | ----- | +| **`traceName`** | string | Name of the trace to set its attribute. | 6.3.0 | +| **`attribute`** | string | Name of the attribute to set its value. | 6.3.0 | +| **`value`** | string | The value to set to the attribute. | 6.3.0 | + + +#### GetAttributeResult + +| Prop | Type | Description | Since | +| ----------- | --------------------------- | ---------------------------------- | ----- | +| **`value`** | string \| null | The value of the custom attribute. | 6.3.0 | + + +#### GetAttributeOptions + +| Prop | Type | Description | Since | +| --------------- | ------------------- | -------------------------------------------- | ----- | +| **`traceName`** | string | Name of the trace to set its attribute. | 6.3.0 | +| **`attribute`** | string | Name of the attribute to retrieve its value. | 6.3.0 | + + +#### GetAttributesResult + +| Prop | Type | Description | Since | +| ------------ | --------------------------------------- | ------------------------------------------------------------ | ----- | +| **`result`** | { [key: string]: string; } | A map of all custom attributes of a trace with their values. | 6.3.0 | + + +#### GetAttributesOptions + +| Prop | Type | Description | Since | +| --------------- | ------------------- | ---------------------------------------- | ----- | +| **`traceName`** | string | Name of the trace to get its attributes. | 6.3.0 | + + +#### PutMetricOptions + +| Prop | Type | Description | Since | +| ---------------- | ------------------- | ---------------------------------------------------------------------------------------- | ----- | +| **`traceName`** | string | Name of the trace to set its metric. | 6.3.0 | +| **`metricName`** | string | The metric name. | 6.3.0 | +| **`num`** | number | The value to set for the metric. The given value is floored down to the nearest integer. | 6.3.0 | + + +#### GetMetricResult + +| Prop | Type | Description | Since | +| ----------- | ------------------- | ---------------------------------- | ----- | +| **`value`** | number | The value of the metric if exists. | 6.3.0 | + + +#### GetMetricOptions + +| Prop | Type | Description | Since | +| ---------------- | ------------------- | ------------------------------------ | ----- | +| **`traceName`** | string | Name of the trace to get its metric. | 6.3.0 | +| **`metricName`** | string | The metric name. | 6.3.0 | + + +#### RecordOptions + +| Prop | Type | Description | Since | +| --------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----- | +| **`traceName`** | string | Name of the trace to record. | 6.3.0 | +| **`startTime`** | number | Start time of the trace since epoch in milliseconds. | 6.3.0 | +| **`duration`** | number | The duration of the trace in milliseconds. | 6.3.0 | +| **`options`** | { metrics?: { [key: string]: number; }; attributes?: { [key: string]: string; }; } | An optional object that holds optional maps of custom metrics and attributes. | 6.3.0 | + + +### Type Aliases + + +#### RemoveAttributeOptions + +GetAttributeOptions + ## Changelog diff --git a/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformance.java b/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformance.java index a32e5f41..46c19870 100644 --- a/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformance.java +++ b/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformance.java @@ -2,6 +2,7 @@ import com.google.firebase.perf.metrics.Trace; import java.util.HashMap; +import java.util.Map; public class FirebasePerformance { @@ -39,6 +40,30 @@ public Boolean isEnabled() { return this.getFirebasePerformanceInstance().isPerformanceCollectionEnabled(); } + public static void putAttribute(Trace trace, String attribute, String value) { + trace.putAttribute(attribute, value); + } + + public static String getAttribute(Trace trace, String attribute) { + return trace.getAttribute(attribute); + } + + public static Map getAttributes(Trace trace) { + return trace.getAttributes(); + } + + public static void removeAttribute(Trace trace, String attribute) { + trace.removeAttribute(attribute); + } + + public static void putMetric(Trace trace, String metricName, long num) { + trace.putMetric(metricName, num); + } + + public static long getMetric(Trace trace, String metricName) { + return trace.getLongMetric(metricName); + } + private com.google.firebase.perf.FirebasePerformance getFirebasePerformanceInstance() { return com.google.firebase.perf.FirebasePerformance.getInstance(); } diff --git a/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformancePlugin.java b/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformancePlugin.java index e51d144e..451fb42a 100644 --- a/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformancePlugin.java +++ b/packages/performance/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/performance/FirebasePerformancePlugin.java @@ -7,6 +7,7 @@ import com.getcapacitor.PluginMethod; import com.getcapacitor.annotation.CapacitorPlugin; import com.google.firebase.perf.metrics.Trace; +import java.util.Map; @CapacitorPlugin(name = "FirebasePerformance") public class FirebasePerformancePlugin extends Plugin { @@ -17,6 +18,12 @@ public class FirebasePerformancePlugin extends Plugin { public static final String ERROR_TRACE_NAME_ALREADY_ASSIGNED = "traceName already assigned."; public static final String ERROR_ENABLED_MISSING = "enabled must be provided."; public static final String ERROR_TRACE_NOT_FOUND = "No trace was found with the provided traceName."; + public static final String ERROR_ATTRIBUTE_MISSING = "attribute must be provided."; + public static final String ERROR_VALUE_MISSING = "value must be provided."; + public static final String ERROR_NUM_MISSING = "num must be provided."; + public static final String ERROR_START_TIME_MISSING = "startTime must be provided."; + public static final String ERROR_DURATION_MISSING = "duration must be provided."; + public static final String ERROR_INVALID_METRIC_VALUE = "provided metric value is not a number."; private FirebasePerformance implementation = new FirebasePerformance(); @PluginMethod @@ -116,4 +123,180 @@ public void isEnabled(PluginCall call) { call.reject(exception.getMessage()); } } + + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void putAttribute(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(FirebasePerformancePlugin.ERROR_TRACE_NAME_MISSING); + return; + } + String attribute = call.getString("attribute"); + if (attribute == null) { + call.reject(FirebasePerformancePlugin.ERROR_ATTRIBUTE_MISSING); + return; + } + String value = call.getString("value"); + if (value == null) { + call.reject(FirebasePerformancePlugin.ERROR_VALUE_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + FirebasePerformance.putAttribute(trace, attribute, value); + call.resolve(); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_PROMISE) + public void getAttribute(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(FirebasePerformancePlugin.ERROR_TRACE_NAME_MISSING); + return; + } + String attribute = call.getString("attribute"); + if (attribute == null) { + call.reject(FirebasePerformancePlugin.ERROR_ATTRIBUTE_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + String value = FirebasePerformance.getAttribute(trace, attribute); + JSObject result = new JSObject(); + result.put("value", value); + call.resolve(result); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_PROMISE) + public void getAttributes(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(ERROR_TRACE_NAME_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + Map attributesMap = FirebasePerformance.getAttributes(trace); + JSObject result = new JSObject(); + JSObject resultMap = new JSObject(); + for (String attribute : attributesMap.keySet()) { + resultMap.put(attribute, attributesMap.get(attribute)); + } + result.put("result", resultMap); + call.resolve(result); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void removeAttribute(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(FirebasePerformancePlugin.ERROR_TRACE_NAME_MISSING); + return; + } + String attribute = call.getString("attribute"); + if (attribute == null) { + call.reject(FirebasePerformancePlugin.ERROR_ATTRIBUTE_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + FirebasePerformance.removeAttribute(trace, attribute); + call.resolve(); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void putMetric(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(FirebasePerformancePlugin.ERROR_TRACE_NAME_MISSING); + return; + } + String metricName = call.getString("metricName"); + if (metricName == null) { + call.reject(FirebasePerformancePlugin.ERROR_METRIC_NAME_MISSING); + return; + } + Double num = call.getDouble("num"); + if (num == null) { + call.reject(FirebasePerformancePlugin.ERROR_NUM_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + FirebasePerformance.putMetric(trace, metricName, (long) Math.floor(num)); + call.resolve(); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_PROMISE) + public void getMetric(PluginCall call) { + try { + String traceName = call.getString("traceName"); + if (traceName == null) { + call.reject(FirebasePerformancePlugin.ERROR_TRACE_NAME_MISSING); + return; + } + String metricName = call.getString("metricName"); + if (metricName == null) { + call.reject(FirebasePerformancePlugin.ERROR_METRIC_NAME_MISSING); + return; + } + Trace trace = implementation.getTraceByName(traceName); + if (trace == null) { + call.reject(ERROR_TRACE_NOT_FOUND); + return; + } + long value = FirebasePerformance.getMetric(trace, metricName); + JSObject result = new JSObject(); + result.put("value", value); + call.resolve(result); + } catch (Exception exception) { + Logger.error(TAG, exception.getMessage(), exception); + call.reject(exception.getMessage()); + } + } + + @PluginMethod(returnType = PluginMethod.RETURN_NONE) + public void record(PluginCall call) { + call.unimplemented("Not implemented on Android."); + } } diff --git a/packages/performance/ios/Plugin/FirebasePerformance.swift b/packages/performance/ios/Plugin/FirebasePerformance.swift index f34ad09b..6e297289 100644 --- a/packages/performance/ios/Plugin/FirebasePerformance.swift +++ b/packages/performance/ios/Plugin/FirebasePerformance.swift @@ -43,4 +43,28 @@ import FirebasePerformance @objc public func isEnabled() -> Bool { return Performance.sharedInstance().isDataCollectionEnabled } + + @objc public static func putAttribute(_ trace: Trace, _ attribute: String, _ value: String) { + trace.setValue(value, forAttribute: attribute) + } + + @objc public static func getAttribute(_ trace: Trace, _ attribute: String) -> String? { + return trace.value(forAttribute: attribute) + } + + @objc public static func getAttributes(_ trace: Trace) -> [String: String] { + return trace.attributes + } + + @objc public static func removeAttribute(_ trace: Trace, _ attribute: String) { + trace.removeAttribute(attribute) + } + + @objc public static func putMetric(_ trace: Trace, _ metricName: String, _ num: Double) { + trace.setValue(Int64(floor(num)), forMetric: metricName) + } + + @objc public static func getMetric(_ trace: Trace, _ metricName: String) -> Int64 { + return trace.valueForMetric(metricName) + } } diff --git a/packages/performance/ios/Plugin/FirebasePerformancePlugin.m b/packages/performance/ios/Plugin/FirebasePerformancePlugin.m index f5b9a4c9..4fdddf4e 100644 --- a/packages/performance/ios/Plugin/FirebasePerformancePlugin.m +++ b/packages/performance/ios/Plugin/FirebasePerformancePlugin.m @@ -9,4 +9,11 @@ CAP_PLUGIN_METHOD(incrementMetric, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(setEnabled, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(isEnabled, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(putAttribute, CAPPluginReturnNone); + CAP_PLUGIN_METHOD(getAttribute, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(getAttributes, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(removeAttribute, CAPPluginReturnNone); + CAP_PLUGIN_METHOD(putMetric, CAPPluginReturnNone); + CAP_PLUGIN_METHOD(getMetric, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(record, CAPPluginReturnNone); ) diff --git a/packages/performance/ios/Plugin/FirebasePerformancePlugin.swift b/packages/performance/ios/Plugin/FirebasePerformancePlugin.swift index ff8c335d..111a9b96 100644 --- a/packages/performance/ios/Plugin/FirebasePerformancePlugin.swift +++ b/packages/performance/ios/Plugin/FirebasePerformancePlugin.swift @@ -12,6 +12,11 @@ public class FirebasePerformancePlugin: CAPPlugin { public let errorEnabledMissing = "enabled must be provided." public let errorTraceNameAlreadyAssigned = "traceName already assigned." public let errorTraceNotFound = "No trace was found with the provided traceName." + public let errorAttributeMissing = "attribute must be provided." + public let errorValueMissing = "value must be provided." + public let errorNumMissing = "num must be provided." + public let errorStartTimeMissing = "startTime must be provided." + public let errorDurationMissing = "duration must be provided." private var implementation: FirebasePerformance? override public func load() { @@ -80,4 +85,120 @@ public class FirebasePerformancePlugin: CAPPlugin { result["enabled"] = enabled call.resolve(result) } + + @objc func putAttribute(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + guard let attribute = call.getString("attribute") else { + call.reject(errorAttributeMissing) + return + } + guard let value = call.getString("value") else { + call.reject(errorValueMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + FirebasePerformance.putAttribute(trace!, attribute, value) + call.resolve() + } + + @objc func getAttribute(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + guard let attribute = call.getString("attribute") else { + call.reject(errorAttributeMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + var result = JSObject() + result["value"] = FirebasePerformance.getAttribute(trace!, attribute) ?? NSNull() + call.resolve(result) + } + + @objc func getAttributes(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + call.resolve(["result": FirebasePerformance.getAttributes(trace!)]) + } + + @objc func removeAttribute(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + guard let attribute = call.getString("attribute") else { + call.reject(errorAttributeMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + FirebasePerformance.removeAttribute(trace!, attribute) + call.resolve() + } + + @objc func putMetric(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + guard let metricName = call.getString("metricName") else { + call.reject(errorMetricNameMissing) + return + } + guard let num = call.getDouble("num") else { + call.reject(errorNumMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + FirebasePerformance.putMetric(trace!, metricName, num) + call.resolve() + } + + @objc func getMetric(_ call: CAPPluginCall) { + guard let traceName = call.getString("traceName") else { + call.reject(errorTraceNameMissing) + return + } + guard let metricName = call.getString("metricName") else { + call.reject(errorMetricNameMissing) + return + } + let trace = implementation?.getTraceByName(traceName) + guard trace != nil else { + call.reject(errorTraceNotFound) + return + } + let value = FirebasePerformance.getMetric(trace!, metricName) + call.resolve(["value": value]) + } + + @objc func record(_ call: CAPPluginCall) { + call.unimplemented("Not implemented on iOS.") + } } diff --git a/packages/performance/src/definitions.ts b/packages/performance/src/definitions.ts index 883fe31b..8da6ab5e 100644 --- a/packages/performance/src/definitions.ts +++ b/packages/performance/src/definitions.ts @@ -30,6 +30,49 @@ export interface FirebasePerformancePlugin { * @since 0.1.0 */ isEnabled(): Promise; + /** + * Sets a custom attribute of a trace to a given value. + * + * @since 6.3.0 + */ + putAttribute(options: PutAttributeOptions): Promise; + /** + * Returns the value of a custom attribute of a trace. + * + * @since 6.3.0 + */ + getAttribute(options: GetAttributeOptions): Promise; + /** + * Gets the all the custom attributes of a trace with their values. + * + * @since 6.3.0 + */ + getAttributes(options: GetAttributesOptions): Promise; + /** + * Removes a custom attribute from a trace given its name. + * + * @since 6.3.0 + */ + removeAttribute(options: RemoveAttributeOptions): Promise; + /** + * Sets the value of a custom metric. + * + * @since 6.3.0 + */ + putMetric(options: PutMetricOptions): Promise; + /** + * Get the value of a custom metric by name. + * + * @since 6.3.0 + */ + getMetric(options: GetMetricOptions): Promise; + /** + * Records a trace given its name and options. + * Only available on web. + * + * @since 6.3.0 + */ + record(options: RecordOptions): Promise; } /** @@ -105,3 +148,182 @@ export interface IsEnabledResult { */ enabled: boolean; } + +/** + * @since 6.3.0 + */ +export interface PutAttributeOptions { + /** + * Name of the trace to set its attribute. + * + * @since 6.3.0 + */ + traceName: string; + /** + * Name of the attribute to set its value. + * + * @since 6.3.0 + * @example "experiment" + */ + attribute: string; + /** + * The value to set to the attribute. + * + * @since 6.3.0 + * @example "A" + */ + value: string; +} + +/** + * @since 6.3.0 + */ +export interface GetAttributeOptions { + /** + * Name of the trace to set its attribute. + * + * @since 6.3.0 + */ + traceName: string; + /** + * Name of the attribute to retrieve its value. + * + * @since 6.3.0 + */ + attribute: string; +} + +/** + * @since 6.3.0 + */ +export interface GetAttributeResult { + /** + * The value of the custom attribute. + * + * @since 6.3.0 + */ + value: string | null; +} + +/** + * @since 6.3.0 + */ +export interface GetAttributesOptions { + /** + * Name of the trace to get its attributes. + * + * @since 6.3.0 + */ + traceName: string; +} + +/** + * @since 6.3.0 + */ +export interface GetAttributesResult { + /** + * A map of all custom attributes of a trace with their values. + * + * @since 6.3.0 + */ + result: { [key: string]: string }; +} + +/** + * @since 6.3.0 + */ +export type RemoveAttributeOptions = GetAttributeOptions; + +/** + * @since 6.3.0 + */ +export interface PutMetricOptions { + /** + * Name of the trace to set its metric. + * + * @since 6.3.0 + */ + traceName: string; + /** + * The metric name. + * + * @since 6.3.0 + */ + metricName: string; + /** + * The value to set for the metric. + * The given value is floored down to the nearest integer. + * + * @since 6.3.0 + */ + num: number; +} + +/** + * @since 6.3.0 + */ +export interface GetMetricOptions { + /** + * Name of the trace to get its metric. + * + * @since 6.3.0 + */ + traceName: string; + /** + * The metric name. + * + * @since 6.3.0 + */ + metricName: string; +} + +/** + * @since 6.3.0 + */ +export interface GetMetricResult { + /** + * The value of the metric if exists. + * + * @since 6.3.0 + */ + value: number; +} + +/** + * @since 6.3.0 + */ +export interface RecordOptions { + /** + * Name of the trace to record. + * + * @since 6.3.0 + */ + traceName: string; + /** + * Start time of the trace since epoch in milliseconds. + * + * @since 6.3.0 + */ + startTime: number; + /** + * The duration of the trace in milliseconds. + * + * @since 6.3.0 + */ + duration: number; + /** + * An optional object that holds optional maps of custom metrics and attributes. + * + * @since 6.3.0 + */ + options?: { + /** + * An optional map of metrics to be set on the trace. + */ + metrics?: { [key: string]: number }; + /** + * An optional map of attributes to be set on the trace. + */ + attributes?: { [key: string]: string }; + }; +} diff --git a/packages/performance/src/web.ts b/packages/performance/src/web.ts index 4ed70e48..769b5d74 100644 --- a/packages/performance/src/web.ts +++ b/packages/performance/src/web.ts @@ -1,16 +1,27 @@ import { WebPlugin } from '@capacitor/core'; import type { PerformanceTrace } from 'firebase/performance'; -import { getPerformance, trace as createTrace } from 'firebase/performance'; +import { trace as createTrace, getPerformance } from 'firebase/performance'; import type { FirebasePerformancePlugin, + GetAttributeOptions, + GetAttributeResult, + GetAttributesOptions, + GetAttributesResult, + GetMetricResult, IncrementMetricOptions, IsEnabledResult, + PutAttributeOptions, + PutMetricOptions, + RecordOptions, + RemoveAttributeOptions, SetEnabledOptions, StartTraceOptions, StopTraceOptions, } from './definitions'; +const traceNotFoundError = 'No trace found for the given name.'; + export class FirebasePerformanceWeb extends WebPlugin implements FirebasePerformancePlugin @@ -54,4 +65,83 @@ export class FirebasePerformanceWeb }; return result; } + + public async putAttribute({ + traceName, + attribute, + value, + }: PutAttributeOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + return; + } + trace.putAttribute(attribute, value); + return; + } + + public async getAttribute({ + traceName, + attribute, + }: GetAttributeOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + throw new Error(traceNotFoundError); + } + return { value: trace.getAttribute(attribute) ?? null }; + } + + public async getAttributes({ + traceName, + }: GetAttributesOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + throw new Error(traceNotFoundError); + } + return { result: trace.getAttributes() }; + } + + public async removeAttribute({ + traceName, + attribute, + }: RemoveAttributeOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + throw new Error(traceNotFoundError); + } + trace.removeAttribute(attribute); + } + + public async putMetric({ + traceName, + metricName, + num, + }: PutMetricOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + throw new Error(traceNotFoundError); + } + trace.putMetric(metricName, num); + } + + public async getMetric({ + traceName, + metricName, + }: PutMetricOptions): Promise { + const trace = this.traces[traceName]; + if (!trace) { + throw new Error(traceNotFoundError); + } + return { value: trace.getMetric(metricName) }; + } + + public async record({ + traceName, + startTime, + duration, + options, + }: RecordOptions): Promise { + const perf = getPerformance(); + const trace = createTrace(perf, traceName); + trace.record(startTime, duration, options); + } }