Skip to content

Conversation

@IlyaPasternakAmitech
Copy link

🎯 Summary
This PR introduces a new prop forbiddenBarcodeTypes, allowing developers to specify an array of barcode types that should be ignored during scanning.

🐛 Problem
In scenarios where multiple barcodes are present in the camera's field of view (e.g., a QR code with advertising data and a product barcode), only the first detected barcode is passed to the onBarcodeRead callback. This often results in missing the desired product barcode, which appears later in the detection sequence.

✅ Solution
The proposed solution adds a new optional prop:

forbiddenBarcodeTypes?: CodeFormat[]

When provided, this prop filters out any detected barcode whose type matches one of the values in the array before invoking the onBarcodeRead callback. This allows developers to skip irrelevant or unwanted barcode types (like advertising QR codes) and wait for the correct barcode to be scanned.

📚 Documentation
If this change is accepted and considered valuable, I'm happy to update the documentation with:

  • A detailed description of the forbiddenBarcodeTypes prop
  • A usage example
  • A list of common barcode types users may want to filter out

Just let me know!

@IlyaPasternakAmitech IlyaPasternakAmitech changed the title Add forbiddenBarcodeTypes property feat: Add forbiddenBarcodeTypes property Jun 16, 2025
@scarlac
Copy link
Collaborator

scarlac commented Jun 23, 2025

Hi @IlyaPasternakAmitech I really like this idea, however I think the best use case would be the reverse - an allow list.
The issue is mainly that as we add features, including bar code types, devs have to increase the list of blacklisted codes, if they don't want to search for them. This means existing apps can break as they upgrade minor versions, based on the same use case you outline (multiple codes in the same view).

So the suggestion is simply to flip the behavior, so instead of:
forbiddenBarcodeTypes?: CodeFormat[]
it becomes:
allowedBarcodeTypes?: CodeFormat[]
If the array is left empty, all codes, current and future ones, are allowed.

The benefit is that it's also easier to achieve faster QR code scanning, as you can simply state which codes you want supported, and then it only spends time looking for those.

What do you think?

@IlyaPasternakAmitech
Copy link
Author

Hi @scarlac, thanks for the feedback!

I understand your point about using an allow list approach (allowedBarcodeTypes) — it makes sense in many cases and could help avoid issues when new barcode types are added in the future.

However, in my use case, I find the blocklist approach (forbiddenBarcodeTypes) more practical. Here's why:

🔍 Use Case: Filter Out Only a Few Specific Barcode Types
In our app, we want to scan only product barcodes, but often there are advertising QR codes in the same field of view.

Using a blacklist allows us to simply block those unwanted QR codes, while still detecting any other barcode type that may appear — without having to explicitly allow each one.

With an allow list , we would have to specify every single barcode type we support (e.g., EAN13, UPC_A, etc.), which is less flexible and harder to maintain.

🔄 Proposed Solution: Mutual Exclusivity Between Both Props
To make this work for both use cases, I propose allowing either forbiddenBarcodeTypes or allowedBarcodeTypes, but not both at once.

This way:

Developers can choose whichever fits their use case better.
We prevent ambiguous configurations.
The logic remains clean and predictable.
Example usage:

// Option 1: Block specific barcode types
<BarcodeScanner forbiddenBarcodeTypes={['qr']} />

// Option 2: Allow only specific barcode types
<BarcodeScanner allowedBarcodeTypes={['code-128', 'code-39', 'code-93', 'codabar', 'ean-13', 'ean-8', 'itf', 'upc-a', 'upc-e', 'pdf-417', 'aztec', 'data-matrix']} />

If both props are provided, we can throw a runtime error or ignore one of them.

@IlyaPasternakAmitech
Copy link
Author

Hi @scarlac,

I’ve updated the PR based on your suggestion — I changed the logic and replaced forbiddenBarcodeTypes with allowedBarcodeTypes. The new prop works as we discussed: if provided, the scanner will only recognize the specified barcode types, making scanning more precise and future-proof.

Also, I’d like to remind you of my previous proposal to support both approaches using two mutually exclusive props — either allowedBarcodeTypes or forbiddenBarcodeTypes. If you think that would be useful, I can implement it in a separate PR.

If these current changes look good to you, feel free to merge them. I'd love to hear your thoughts!

Thanks!

hasCameraBeenSetup = true
#if targetEnvironment(macCatalyst)
// Force front camera on Mac Catalyst during initial setup
camera.setup(cameraType: .front, supportedBarcodeType: scanBarcode && onReadCode != nil ? supportedBarcodeType : [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we still need supportedBarcodeType class variable?

}
private func setupCamera() {
if hasPropBeenSetup && hasPermissionBeenGranted && !hasCameraBeenSetup {
let allowedBarcodeTypes = convertAllowedBarcodeTypes()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure it's a good thing to hide allowedBarcodeTypes class variable by using the same name
it can be source of tricky error

private var frameColor = Color.GREEN
private var laserColor = Color.RED
private var barcodeFrameSize: Size? = null
private var allowedBarcodeTypes: ReadableArray? = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make it more meaningful with an Array<CodeFormat>

@@ -143,6 +143,11 @@ class CKCameraManager : SimpleViewManager<CKCamera>(), CKCameraManagerInterface<
view.setShutterPhotoSound(enabled);
}

@ReactProp(name = "allowedBarcodeTypes")
override fun setAllowedBarcodeTypes(view: CKCamera, types: ReadableArray?) {
view.setAllowedBarcodeTypes(types)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to do the conversion to Array<CodeFormat> straight here, then forward result to the view

  • it gets rid of incorrect values right away
  • it avoids doing it on every single barcode scanned

val filteredByType = if (allowedTypes.isEmpty()) {
barcodes
} else {
barcodes.filter { barcode ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@DavidBertet DavidBertet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice contribution! I wanted to do it for quite some time!

Don't forget to update the doc, so everyone is aware of it. I think it's been requested in the past!

# Conflicts:
#	android/src/main/java/com/rncamerakit/CKCamera.kt
#	android/src/newarch/java/com/rncamerakit/CKCameraManager.kt
#	android/src/paper/java/com/facebook/react/viewmanagers/CKCameraManagerDelegate.java
#	android/src/paper/java/com/facebook/react/viewmanagers/CKCameraManagerInterface.java
@IlyaPasternakAmitech
Copy link
Author

@scarlac and @DavidBertet,

I would like to express my gratitude for your valuable feedback and suggestions.

Thank you, @VishaKsu, for updating the pull request.

Thank you all for your patience and valuable contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants