npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-goodflip-bca-height

v0.1.1

Published

GoodFlip BCA Height SDK for React Native

Readme

react-native-goodflip-bca-height

This project is a minimal React Native app showing how to integrate **react-native-goodflip-bca-height** – a GoodFlip smart scale (weight + height) SDK wrapper – on Android and iOS, including the required **react-native-permissions setup.

The app:

  • Initializes the GoodFlip SDK once at startup
  • Scans for nearby GoodFlip height/weight scales over BLE
  • Connects to a selected device with user info (id, height, gender, birthday)
  • Streams live weight while the user is on the scale
  • Displays a final measurement result (weight, height, and itemized scale data)

1. Overview

**react-native-goodflip-bca-height provides:

  • BLE-based connection to GoodFlip height/weight smart scales
  • User profile (id, height, gender, birthday) for measurements
  • Device events: scan started/stopped, device discovered, connection state, live weight, final result
  • Native Bluetooth & location permissions handled via **react-native-permissions** (iOS) and the **Android manifest**

In this demo app, all GoodFlip interactions live in App.tsx:

  • initGoodFlipSdk() initializes the SDK on mount
  • attachGoodFlipListeners() subscribes to device/scan/measurement events
  • startGoodFlipScan() / stopGoodFlipScan() control scanning
  • connectGoodFlipDevice(...) connects and triggers a measurement with user data
  • disconnectGoodFlipDevice(...) cleans up the connection

2. Required Packages

Core dependencies

These are used and already installed in this project (see package.json):

| Package | Purpose | | ---------------------------------- | --------------------------------------------------------------------------------------- | | react-native-goodflip-bca-height | Main integration package for GoodFlip height/weight scales (BLE scanning and measuring) |

Peer / supporting dependencies

| Package | Purpose | | -------------------------- | ---------------------------------------------------------------------------------- | | react-native-permissions | iOS: Bluetooth & Location permission configuration via Podfile setup_permissions |

Note: The GoodFlip library bundles its required native BLE SDKs and other Android/iOS libraries. You do not need to add extra BLE libraries in Gradle or CocoaPods beyond what react-native-goodflip-bca-height pulls in.


3. React Native Setup

3.1 Install dependencies

From your project root:

npm install react-native-goodflip-bca-height react-native-permissions
# or
yarn add react-native-goodflip-bca-height react-native-permissions

Autolinking (React Native 0.60+) handles the native modules for both platforms.

3.2 Rebuild the app

After installing the packages and applying the Android/iOS config below:

# Android
npx react-native run-android

# iOS
cd ios && pod install && cd ..
npx react-native run-ios

4. Android Integration

This project is already configured; use this section to mirror the setup in your own app.

4.1 Minimum SDK and compile/target

android/build.gradle:

  • **minSdkVersion**: 24
  • **compileSdkVersion**: 36
  • **targetSdkVersion**: 36

These are exposed via the shared Gradle ext block and used by android/app/build.gradle:

buildscript {
  ext {
    buildToolsVersion = "36.0.0"
    minSdkVersion = 24
    compileSdkVersion = 36
    targetSdkVersion = 36
  }
}

Make sure your app uses at least these versions so the GoodFlip SDK can build and run correctly.

4.2 Bluetooth & Location permissions

This app declares all relevant BLE and location permissions in android/app/src/main/AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

In your own project, ensure at least:

  • INTERNET
  • ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION
  • BLUETOOTH / BLUETOOTH_ADMIN (for API < 31, usually with android:maxSdkVersion="30")
  • BLUETOOTH_SCAN
  • BLUETOOTH_CONNECT

The GoodFlip SDK will rely on these for BLE scanning and connecting.

4.3 Build & run

cd android
./gradlew clean
cd ..
npx react-native run-android

For real BLE testing, use a physical Android device with Bluetooth and (if needed) Location enabled.


5. iOS Integration

This project’s iOS side is already wired for react-native-goodflip-bca-height and react-native-permissions.

5.1 Podfile – permissions setup

ios/Podfile:

  • Loads the react-native-permissions setup script
  • Enables Bluetooth and Location permissions via setup_permissions
  • Excludes arm64 for the simulator to avoid framework arch issues

Key parts:

# At the top of your Podfile (after require)
permissions_setup_path = File.expand_path('../node_modules/react-native-permissions/scripts/setup.rb', __dir__)
require permissions_setup_path

platform :ios, min_ios_version_supported
prepare_react_native_project!

linkage = ENV['USE_FRAMEWORKS']
if linkage != nil
  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
  use_frameworks! :linkage => linkage.to_sym
else
  use_frameworks! :linkage => :static
end

setup_permissions([
  'Bluetooth',
  'BluetoothPeripheral',
  'Notifications',
  'LocationWhenInUse',
])

# Add this line above "use_react_native!" block
use_frameworks! :linkage => :static

#Place this inside you target block
post_install do |installer|
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false,
      # :ccache_enabled => true
    )

    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
        config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
      end

      if target.name == 'QNSDK'
        target.build_configurations.each do |config|
          config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
          config.build_settings['WARNING_CFLAGS'] = '-Wno-error -Wno-narrowing'
          config.build_settings['OTHER_CFLAGS'] = '$(inherited) -Wno-error -Wno-narrowing'
        end
      end
    end

    installer.aggregate_targets.each do |aggregate_target|
      aggregate_target.user_project.native_targets.each do |native_target|
        native_target.build_configurations.each do |config|
          config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
        end
      end
    end

    qn_config = 'Pods/QNSDK/QNSDK/SDK/QNConfig.h'
    if File.exist?(qn_config)
      content = File.read(qn_config)
      patched = content.gsub('NS_ENUM(NSUInteger,', 'NS_ENUM(NSInteger,')
      if content != patched
        FileUtils.chmod(0644, qn_config)
        File.write(qn_config, patched)
        puts "Patched QNSDK QNConfig.h: NSUInteger -> NSInteger"
      end
    end
  end

If you are migrating this setup, make sure:

  • permissions_setup_path and require permissions_setup_path are at the top
  • setup_permissions([...]) includes at least Bluetooth and LocationWhenInUse
  • The post_install block sets EXCLUDED_ARCHS[sdk=iphonesimulator*] = 'arm64' for simulator targets

Then run:

cd ios
pod install
cd ..

5.2 Info.plist usage descriptions

ios/demo_app/Info.plist already declares the required permission usage strings:

<!-- Bluetooth (scan/connect/advertise) -->
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app uses Bluetooth to scan for and connect to your smart scale.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app uses Bluetooth to communicate with your smart scale.</string>

<!-- Location (needed by iOS when scanning BLE in many cases) -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location while in use to detect nearby Bluetooth devices.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs your location even in the background to stay connected to your smart scale.</string>

In your own app, customize these strings, but keep the keys so iOS will show the Bluetooth and Location permission prompts.

5.3 Build & run

cd ios
pod install
cd ..
npx react-native run-ios

BLE will only work on a real iOS device with Bluetooth enabled. The simulator is useful to verify builds and UI only.


6. Usage in Code (from this demo)

All integration happens in App.tsx. The flow is:

  1. Initialize SDK on mount with initGoodFlipSdk()
  2. Attach listeners with attachGoodFlipListeners(...)
  3. Start scanning with startGoodFlipScan()
  4. Connect to a selected device with connectGoodFlipDevice(...) and user info
  5. Show live weight and final result from listener callbacks
  6. Clean up listeners, scanning, and connections on unmount

Simplified example based on this project:

import { useEffect, useRef, useState } from 'react';
import {
  initGoodFlipSdk,
  attachGoodFlipListeners,
  startGoodFlipScan,
  stopGoodFlipScan,
  connectGoodFlipDevice,
  disconnectGoodFlipDevice,
} from 'react-native-goodflip-bca-height';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { Button, Text, View } from 'react-native';

const USER = {
  id: 'user-001',
  height: 170,
  gender: 'male' as const,
  birthday: '1990-05-20',
};

export default function App() {
  const [devices, setDevices] = useState<any[]>([]);
  const [liveWeight, setLiveWeight] = useState<number | null>(null);
  const [result, setResult] = useState<any | null>(null);
  const listenersRef = useRef<{ remove(): void } | null>(null);

  useEffect(() => {
    let mounted = true;

    const run = async () => {
      await initGoodFlipSdk();
      if (!mounted) return;

      listenersRef.current = attachGoodFlipListeners({
        onDeviceDiscovered: (device) => {
          setDevices((prev) =>
            prev.find((d) => d.mac === device.mac) ? prev : [...prev, device]
          );
        },
        onUnsteadyWeight: (weight) => setLiveWeight(weight),
        onScaleData: (data) => {
          setResult(data);
          setLiveWeight(null);
        },
      });
    };

    run();

    return () => {
      mounted = false;
      listenersRef.current?.remove();
      disconnectGoodFlipDevice().catch(() => {});
      stopGoodFlipScan().catch(() => {});
    };
  }, []);

  const startScan = () => {
    setDevices([]);
    startGoodFlipScan().catch(() => {});
  };

  const connect = (mac: string) => {
    connectGoodFlipDevice(
      mac,
      USER.id,
      USER.height,
      USER.gender,
      USER.birthday
    ).catch(() => {});
  };

  return (
    <SafeAreaProvider>
      {/* UI for scanning, listing devices, connecting, and showing results */}
    </SafeAreaProvider>
  );
}

Refer to App.tsx in this repo for the full example including UI state (screens, scanning indicator, errors, etc.).


7. API Reference (as used in this app)

The exact surface area of react-native-goodflip-bca-height may be larger; this is the subset used in this project.

Core functions

| Function | Description | | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | initGoodFlipSdk(): Promise<{ sdkReady: boolean; message?: string; error?: string }> | Initialize the GoodFlip SDK. Called once at app start. | | attachGoodFlipListeners(listeners): { remove(): void } | Subscribe to GoodFlip events (scan, connection, weight, result). Returns a remover. | | startGoodFlipScan(): Promise<void> | Start scanning for GoodFlip scales over BLE. | | stopGoodFlipScan(): Promise<void> | Stop scanning. | | connectGoodFlipDevice(mac, userId, height, gender, birthday): Promise<void> | Connect to a scale and start a measurement with the given user data. | | disconnectGoodFlipDevice(mac?: string): Promise<void> | Disconnect from the current device (the app passes the connected MAC when available). |

Listener callbacks (from this project)

The app passes this object into attachGoodFlipListeners:

  • **onDeviceDiscovered(device)** – called when a device is found during scanning
    Example device shape: { mac, name, rssi }
  • **onScanStarted() / onScanStopped()** – scanning state changes
  • **onScanFailed(errorCode)** – scan failed (error code from native)
  • **onConnectionChanged(event, mac, errorCode)** – connection lifecycle
    event examples: 'connecting', 'connected', 'disconnected', 'connectError'
  • **onUnsteadyWeight(weight)** – live weight updates while the user is still moving
  • **onScaleData(data)** – final result once the measurement is complete
    The app expects:
    • data.mac: device MAC
    • data.weight: final weight in kg
    • data.height: final height in cm (if available)
    • data.items: array of { type, name, value } entries (detailed metrics)

8. Troubleshooting

8.1 “Native module not found” / linking errors

  • Ensure you installed the package:
    • npm install react-native-goodflip-bca-height react-native-permissions
  • Run pod install inside ios/ and rebuild:
    • cd ios && pod install && cd ..
    • npx react-native run-ios
  • For Android, clean and rebuild:
    • cd android && ./gradlew clean && cd ..
    • npx react-native run-android

8.2 Android: scanning or connecting does not work

  • Confirm your device has Bluetooth and Location enabled.
  • Verify the permissions in AndroidManifest.xml (see 4.2).
  • Test on a real device, not only on emulators (emulators often lack proper BLE support).

8.3 iOS: Bluetooth or location prompt never appears

  • Ensure Info.plist has all Bluetooth and Location usage keys (see 5.2).
  • Verify that setup_permissions([...]) in Podfile includes:
    • 'Bluetooth', 'BluetoothPeripheral', 'LocationWhenInUse'
  • Run pod install again after editing the Podfile.

8.4 iOS simulator: build fails due to arm64 or BLE framework

  • This project excludes arm64 for iphonesimulator in the Podfile’s post_install block.
  • Make sure your Podfile has:
    • config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64' for both pods project and the user project targets.
  • Prefer testing BLE on a real iOS device.

8.5 Listener callbacks not firing

  • Ensure initGoodFlipSdk() is called before attachGoodFlipListeners.
  • Make sure you call startGoodFlipScan() to begin scanning.
  • Only call connectGoodFlipDevice(...) after a device has been discovered (e.g. in tap handler on a device row).
  • Do not forget to keep the reference returned by attachGoodFlipListeners and call .remove() on unmount.

9. Summary Checklist (for your own app)

React Native

  • Install: react-native-goodflip-bca-height, react-native-permissions, react-native-safe-area-context
  • Initialize GoodFlip SDK on startup with initGoodFlipSdk
  • Attach listeners via attachGoodFlipListeners
  • Scan & connect using startGoodFlipScan, connectGoodFlipDevice, and show results from callbacks

Android

  • minSdkVersion >= 24, compileSdkVersion/targetSdkVersion >= 34 (this demo uses 36)
  • Add Bluetooth + Location permissions to AndroidManifest.xml
  • Build on a real device for BLE

iOS

  • Configure react-native-permissions in Podfile with setup_permissions([...])
  • Add Bluetooth and Location usage strings in Info.plist
  • Exclude arm64 for the simulator if required by the native frameworks
  • Run pod install and then rebuild

Following the patterns in this demo app, you can plug GoodFlip height/weight scale measurements into your own React Native UI while keeping all native BLE and permission handling encapsulated in react-native-goodflip-bca-height.