typescriptbluetoothelectronweb-bluetooth

Getting "User cancelled the requestDevice() chooser." Error with Electron 17.x + Web Bluetooth


Took a look at the following SO resources:

  1. Web Bluetooth & Chrome Extension: User cancelled the requestDevice() chooser
  2. Electron Web Bluetooth API requestDevice() Error
  3. Can you manipulate web bluetooth chooser that shows after calling requestDevice()?

But their solutions don't seem to be working.

Here's my main file:

import { app, BrowserWindow } from "electron";

/**
 * Ref: https://www.electronjs.org/docs/tutorial/quick-start#create-the-main-script-file
 */
async function createWindow(): Promise<BrowserWindow> {
  // Creating a browser window
  const win = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    },
  });

  /**
   * Handle bluetooth connection
   * Ref: https://www.electronjs.org/docs/latest/tutorial/devices#web-bluetooth-api
   */
  win.webContents.on("select-bluetooth-device", (event, devices, callback) => {
    event.preventDefault();
    if (devices.length > 0) {
      callback(devices[0].deviceId);
    }
  });

  // Load index.html
  win.maximize();
  await win.loadFile("./dist/renderer/index.html");
  return win;
}

function setUpElectronApp(): void {
  // Browser window
  let win: BrowserWindow | undefined;

  // Enable webBluetooth
  app.commandLine.appendSwitch("enable-experimental-web-platform-features", "true");
  app.commandLine.appendSwitch("enable-web-bluetooth", "true");

  // Create bowser window once the electron app is initialized
  app
    .whenReady()
    .then(() => {
      createWindow()
        .then((response) => {
          win = response;
          console.log(win);
        })
        .catch((err) => {
          throw err as Error;
        });
    })
    .catch((err) => {
      throw err as Error;
    });

  // Quit the application when it no longer has any open windows
  app.on("window-all-closed", () => {
    if (process.platform !== "darwin") {
      // The action is no-op on macOS due to the OS' behavior (https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac)
      // On macOS it is common for applications and their menu bar to stay active until the user quits explicitly with Cmd + Q
      app.quit();
      win = undefined;
    }
  });

  // Create a new browser window only when the application has no visible windows being activated
  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      // On macOS it's common to re-create a window in the app when the dock icon is clicked and there are no other windows open.
      createWindow()
        .then((response) => {
          win = response;
          console.log(win);
        })
        .catch((err) => {
          throw err;
        });
    }
  });
}

setUpElectronApp();

Here's some code from the renderer file:

function onDisconnected(event: Event) {
  const device = event.target as BluetoothDevice;
  console.log(`Device ${device.name} is disconnected.`);
}

export async function deviceConnect(): Promise<DeviceInfo> {

  const device = await navigator.bluetooth.requestDevice({
    filters: [
      {
        namePrefix: "Polar Sense",
        manufacturerData: [{ companyIdentifier: 0x006b }], // For 'Polar Electro OY' company.
      },
    ],
    acceptAllDevices: false,
    optionalServices: [0x180d, 0x180f],
  });

  device.addEventListener("gattserverdisconnected", onDisconnected);


  const server = await device.gatt?.connect();

  const heartRateService = await server?.getPrimaryService(0x180d);
  const heartRate = await heartRateService?.getCharacteristic(0x2a37);

  const batteryLevelService = await server?.getPrimaryService(0x180f);
  const batteryLevel = await batteryLevelService?.getCharacteristic(0x2a19);

  return { heartRate, batteryLevel, deviceID: device.name };
}

There's a button in my front which triggers the above function when clicked. Constantly, getting the Uncaught (in promise) DOMException: User cancelled the requestDevice() chooser. error. Tried different versions of Electron as well. Still scratching my head.

Please let me know if accessing Web Bluetooth API in Electron is even possible. Using "electron": "^17.4.7", on a macOS Monterey (12.4).

If you can spot anything, please suggest any issues with the approach above.


Solution

  • Had to enable Bluetooth access for Electron and VSCode via System Preferences.

    enter image description here