Skip to content

Capawesome December 2024 Update

The Capawesome December update is here! This update includes new features and improvements for Capawesome Cloud and our Plugins. There are also some news from the community. Let's take a look at the most important changes.

CLI

login command no longer creates tokens

Until now, the login command created a new token every time you logged in using email and password. However, tokens were originally only intended for the API and CI/CD. To avoid confusion, the login command no longer creates tokens. Instead, a session is created, which is automatically deleted after 30 days of inactivity.

Cloud

Unsubscribe from notifications

You can now unsubscribe from notifications via the Capawesome Cloud Console. Simply navigate to the Notifications page and select the notifications you want to subscribe to or unsubscribe from.

Manage sessions

You can now manage your sessions via the Capawesome Cloud Console. Simply navigate to the Sessions page and view all your active sessions. You can also revoke sessions if needed.

Plugins

Android Foreground Service

The Android Foreground Service plugin now has a new serviceType option that allows you to specify the type of the foreground service:

import { ForegroundService, ServiceType } from '@capawesome-team/capacitor-android-foreground-service';

const startForegroundService = async () => {
  await ForegroundService.startForegroundService({
    id: 1,
    title: 'Recording',
    body: 'Recording audio in the background',
    smallIcon: 'ic_stat_icon_config_sample',
    serviceType: ServiceType.Microphone
  });
};

For now, only two service types are supported. Feel free to open an issue if you are missing a specific service type.

App Shortcuts

We have published a new App Shortcuts plugin that allows you to manage app shortcuts and quick actions on Android and iOS. The plugin can be installed via the public npm registry:

npm install @capawesome/capacitor-app-shortcuts

Here is an example of how to use the plugin:

import { AppShortcuts } from '@capawesome/capacitor-app-shortcuts';

const set = async () => {
  await AppShortcuts.set({
    shortcuts: [
      {
        id: 'feedback',
        title: 'Feedback',
      }
    ],
  });
};
Android iOS

Firebase Analytics

The Firebase Analytics plugin now supports the Firebase JS SDK 11.

Firebase App

The Firebase App plugin now supports the Firebase JS SDK 11.

Firebase App Check

The Firebase App Check plugin now supports the Firebase JS SDK 11.

Firebase Authentication

The Firebase Authentication plugin received multiple updates this month.

Firebase JS SDK 11

The plugin now supports the Firebase JS SDK 11.

Facebook iOS SDK

The Facebook iOS SDK was updated to version 17.1.0.

New idTokenChange listener

The plugin now has a new idTokenChange listener that allows you to listen for changes to the ID token:

import { FirebaseAuthentication } from '@capacitor-firebase/authentication';

const addListener = async () => {
  FirebaseAuthentication.addListener('idTokenChange', async (event) => {
    console.log(event);
  });
};
New verifyBeforeUpdateEmail method

The plugin now has a new verifyBeforeUpdateEmail method that allows you to verify the email before updating it:

import { FirebaseAuthentication } from '@capacitor-firebase/authentication';

const verifyBeforeUpdateEmail = async () => {
  await FirebaseAuthentication.verifyBeforeUpdateEmail({
    newEmail: '[email protected]',
    actionCodeSettings: {
      url: 'https://www.example.com/[email protected]&cartId=123',
      iOS: {
        bundleId: 'com.example.ios'
      },
      android: {
        packageName: 'com.example.android',
        installApp: true,
        minimumVersion: '12'
      },
      handleCodeInApp: true
    }
  });
};

Firebase Cloud Firestore

The Firebase Cloud Firestore plugin now supports the Firebase JS SDK 11.

Firebase Cloud Functions

The Firebase Cloud Functions plugin received multiple updates this month.

Firebase JS SDK 11

The plugin now supports the Firebase JS SDK 11.

New regionOrCustomDomain option

The UseEmulatorOptions interface now has a new regionOrCustomDomain option that allows you to specify the region or custom domain for the emulator:

import { FirebaseFunctions } from '@capacitor-firebase/functions';

const useEmulator = async () => {
  await FirebaseFunctions.useEmulator({
    host: '10.0.2.2',
    port: 9001,
    regionOrCustomDomain: 'us-central1'
  });
};

Firebase Cloud Messaging

The Firebase Cloud Messaging plugin now supports the Firebase JS SDK 11.

Firebase Cloud Storage

The Firebase Cloud Storage plugin now supports the Firebase JS SDK 11.

Firebase Performance Monitoring

The Firebase Performance Monitoring plugin received multiple updates this month.

Firebase JS SDK 11

The plugin plugin now supports the Firebase JS SDK 11.

New methods

The plugin got a few new methods that allow you to put and get attributes and metrics for a trace:

import { FirebasePerformance } from '@capacitor-firebase/performance';

const putAttribute = async () => {
  await FirebasePerformance.putAttribute({
    traceName: 'test_trace',
    attribute: 'user_id',
    value: '123',
  });
};

const getAttribute = async () => {
  const result = await FirebasePerformance.getAttribute({
    traceName: 'test_trace',
    attribute: 'user_id',
  });
  return result.attributes;
};

const getAttributes = async () => {
  const result = await FirebasePerformance.getAttributes({ traceName: 'test_trace' });
  return result.attributes;
};

const removeAttribute = async () => {
  await FirebasePerformance.removeAttribute({
    traceName: 'test_trace',
    attribute: 'user_id',
  });
};

const putMetric = async () => {
  await FirebasePerformance.putMetric({
    traceName: 'test_trace',
    metricName: 'item_cache_hit',
    num: 1,
  });
};

const getMetric = async () => {
  const result = await FirebasePerformance.getMetric({
    traceName: 'test_trace',
    metricName: 'item_cache_hit',
  });
  return result.value;
};

const record = async () => {
  await FirebasePerformance.record({
    traceName: 'test_trace',
    startTime: Date.now(),
    duration: 1000,
    options: {
      metrics: {
        item_cache_hit: 1,
      },
      attributes: {
        user_id: '123',
      },
    },
  });
};

Firebase Remote Config

The Firebase Remote Config plugin now supports the Firebase JS SDK 11.

Live Update

The Live Update plugin received multiple updates this month.

New getCurrentBundle() and getNextBundle() methods

The plugin now has new getCurrentBundle() and getNextBundle() methods that allow you to get the current and next bundle:

import { LiveUpdate } from '@capawesome/capacitor-live-update';

/**
 * Get the bundle identifier of the current bundle. 
 * The current bundle is the bundle that is currently used by the app.
 */
const getCurrentBundle = async () => {
  const { bundleId } = await LiveUpdate.getCurrentBundle();
  return bundleId;
};

/**
 * Get the bundle identifier of the next bundle. 
 * The next bundle is the bundle that will be used after calling `reload()` or restarting the app.
 */
const getNextBundle = async () => {
  const { bundleId } = await LiveUpdate.getNextBundle();
  return bundleId;
};

This change deprecated the getBundle() method.

New setNextBundle(...) method

The plugin now has a new setNextBundle(...) method that allows you to set the next bundle:

import { LiveUpdate } from '@capawesome/capacitor-live-update';

/**
 * Set the next bundle. 
 * The next bundle is the bundle that will be used after calling `reload()` or restarting the app.
 */
const setNextBundle = async () => {
  await LiveUpdate.setNextBundle({
    bundleId: '4b678425-fe57-485d-a8ff-a08af915bd29',
  });
};

This change deprecated the setBundle(...) method.

New channel property

The fetchLatestBundle(...) and sync(...) methods now have a new channel property that allows you to specify the name of the channel where the latest bundle is fetched from:

import { LiveUpdate } from '@capawesome/capacitor-live-update';

/**
 * Fetch the latest bundle from the specified channel.
 */
const fetchLatestBundle = async () => {
  const result = await LiveUpdate.fetchLatestBundle({
    channel: 'production-5',
  });
  return result;
};

/**
 * Sync the latest bundle from the specified channel.
 */
const sync = async () => {
  const result = await LiveUpdate.sync({
    channel: 'production-5',
  });
  return result;
};
New FetchLatestBundleResult properties

The fetchLatestBundle(...) method now returns a artifactType and downloadUrl property:

import { LiveUpdate } from '@capawesome/capacitor-live-update';

const fetchLatestBundle = async () => {
  const result = await LiveUpdate.fetchLatestBundle();
  return {
    artifactType: result.artifactType,
    bundleId: result.bundleId,
    downloadUrl: result.downloadUrl,
  };
};

NFC

The NFC plugin received multiple updates this month.

New manufacturerCode property

The plugin is now also able to read the IC Manufacturer Code for ISO15693 tags:

import { Nfc, NfcTagTechType } from '@capawesome-team/capacitor-nfc';

const readManufacturerCode = async () => {
  return new Promise((resolve) => {
    Nfc.addListener('nfcTagScanned', async (event) => {
      // Stop the NFC scan session
      await Nfc.stopScanSession();
      // Return the IC Manufacturer Code
      resolve(event.nfcTag.manufacturerCode);
    });
    // Start the NFC scan session
    void Nfc.startScanSession();
  });
};
HCE support

The plugin now supports Host Card Emulation (HCE) on Android. This allows you to emulate an NFC tag on your device and respond to commands from an NFC reader. Here is an example of how to use this feature:

import { Nfc } from '@capawesome-team/capacitor-nfc';

const addListener = async () => {
  Nfc.addListener('commandReceived', async (event) => {
    // Do something with the received command
    console.log(event.data);
    // Respond to the command
      await respond({ data: [...] });
  });
};
0x24 command support

The plugin now supports the Write Multiple Blocks command (0x24 command code), as defined in the ISO 15693-3 specification, also on iOS:

import { Nfc, NfcTagTechType } from '@capawesome-team/capacitor-nfc';

const writeMultipleBlocks = async () => {
  return new Promise((resolve) => {
    Nfc.addListener('nfcTagScanned', async (event) => {
      // Write multiple blocks to the NFC tag
      await Nfc.transceive({ 
        techType: NfcTagTechType.NfcV, 
        data: [...], 
        iso15693RequestFlags: [...], 
        iso15693CommandCode: 0x24 
      });
      // Stop the NFC scan session
      await Nfc.stopScanSession();
      resolve();
    });
    // Start the NFC scan session
    void Nfc.startScanSession();
  });
};

Printer

The Printer plugin now also supports the web, at least with the printWebView method:

import { Printer } from '@capawesome-team/capacitor-printer';

const print = async () => {
  await Printer.printWebView({
    content: '<h1>Hello, World!</h1>',
  });
};

You can also use a print style sheet to customize the print output:

@media print {
  h1 {
    color: red;
  }
}

For more information, check out the mdn web docs.

Speech Recognition

We have published a new Speech Recognition plugin that allows you to transcribe speech to text. The plugin supports Android, iOS, and the web. It comes with a simple API that allows you to start and stop the recognition process:

import { SpeechRecognition } from '@capawesome-team/capacitor-speech-recognition';

const startListening = async () => {
  // Print the recognized text to the console
  await SpeechRecognition.addListener('result', (event) => {
    console.log('Result:', event.result);
  });
  // Start listening for speech
  await SpeechRecognition.startListening({
    language: 'en-US',
    silenceThreshold: 2000,
  });
};

Besides that, there are a few special features like the ability to set a silence threshold. The plugin is now available to all Capawesome Insiders.

Speech Synthesis

We have also published a new Speech Synthesis plugin that allows you to convert text to speech. The plugin supports Android, iOS, and the web. You can customize the voice, pitch, and rate of the speech. Here is an example of how to use the plugin:

import { SpeechSynthesis, QueueStrategy } from '@capawesome-team/capacitor-speech-synthesis';

const speak = async () => {
  // Print every spoken word to the console
  await SpeechSynthesis.addListener('boundary', (event) => {
    console.log('boundary', event);
  });
  // Speak the text
  await SpeechSynthesis.speak({
    language: 'en-US',
    pitch: 1.0,
    queueStrategy: QueueStrategy.Add,
    rate: 1.0,
    text: 'Hello, World!',
    voiceId: 'com.apple.ttsbundle.Samantha-compact',
    volume: 1.0,
  });
};

The plugin is now available to all Capawesome Insiders.

Torch

The Torch plugin now also supports the web using the Media Capture and Streams API:

import { Torch } from '@capawesome/capacitor-torch';

const enable = async () => {
  await Torch.enable();
};

Wifi

The Wifi plugin got a new configuration option that allows you to force the usage of the deprecated WifiManager API on Android as there have been several reports that the new WifiNetworkSpecifier API is not yet working as expected on some devices.

You can enable the useWifiManager option in the Capacitor configuration file:

{
  "plugins": {
    "Wifi": {
      "useWifiManager": true
    }
  }
}

Community

Build a mobile app with Qwik and Capacitor

@srapport published the official Qwik for iOS and Android guide this month. The guide explains how to create a mobile app for Android and iOS with Qwik using Capacitor and highlights what you need to pay attention to. This also includes a short introduction to the Capacitor Live Update plugin from Capawesome. Check out the guide here.