DocHub
How barcode scanning works, carrier identification regex patterns, and the scan-to-save flow

Scanning & Carrier Detection

Scanner Implementation

Library: mobile_scanner v4.0.1 Widget: CustomScanner (lib/core/global/widgets/scanner/custom_scanner.dart)

  • Camera resolution: 1920x1080
  • All barcode formats supported (QR, 1D codes, etc.)
  • Adjustable scan window with red border overlay
  • Single-detection mode (prevents duplicate rapid fires)
  • Sound notification on successful scan via SoundService

Scan Flow

  1. User taps SCAN button on Home Page
  2. CustomScanner dialog opens with camera preview
  3. Scanner detects barcode within the scan window
  4. Raw barcode string is extracted
  5. LogisticService.identifyCourier(barcode) identifies the carrier
  6. Display tracking number is extracted (carrier-specific logic)
  7. PackageCheckService queries Firestore to see if package exists
  8. App navigates to Check-In or Package Details screen
  9. User fills form and saves – package written to Firestore with scan history entry

Manual Entry

Users can also enter tracking numbers manually via ManualTrackingNumberController. Same carrier detection and package check flow applies.

Carrier Detection

Service: LogisticService (lib/core/services/logistic_service.dart)

Each carrier is identified by regex pattern matching on the raw barcode:

Carrier Regex Pattern Example
UPS ^1Z\w{16}$ 1ZABC12345678901234
FedEx Multiple: 12-34 digit patterns 96xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (34 digits)
USPS ^9(?!(622|632))\d{21}(\d{4})?$ 9xxx…xxx (22-26 digits, not 9622/9632)
OnTrac ^D100\d{11}$ D10012345678901
LaserShip ^1LS.*$ 1LS…
SpeedX ^SPXPBI\d{12}$ SPXPBI123456789012
GOFO Express ^GFUS01\d{12}$ GFUS01123456789012
DHL ^\d{10}$ 1234567890
Amazon US ^TBA\w{12}$ TBA123456789012
Amazon Canada ^TBC\w+$ TBC…
International ^[A-Z]{2}\d{9}[A-Z]{2}$ AB123456789CD
Max Shipping Contains MAXTRACKS (case insensitive) xxxx-MAXTRACKS
Unknown No pattern match Falls through to unknown

Carrier-Specific Tracking Number Extraction

After identifying the carrier, the app extracts a display tracking number:

  • USPS: Last 22 characters
  • FedEx: Last 12 characters
  • Others: Last 12 characters or full match depending on length

Package Check Service

Service: PackageCheckService (lib/core/services/package_check_service.dart)

After scanning, this service queries the Packages Firestore collection:

  1. Query by trackingNumber field (exact match)
  2. Carrier-specific secondary queries (e.g., last 12/22 chars for USPS/FedEx)
  3. Returns PackageCheckResult with:
    • Whether package exists
    • Full package data if found
    • Status information

Based on the result:

  • Package doesn’t exist: Navigate to new entry form (Check-In or Package Details)
  • Package exists: Navigate to duplicate handling screen (CheckInExist or PackageExists)

Scan History

Every scan operation creates a ScanModel entry appended to the package’s scanHistory array:

Field Type Description
userRole string Role of the scanner (“Receiving”, “Check In”, etc.)
user string User document ID
timestamp timestamp When the scan occurred
note string Optional note from the user
problem string/null Problem type if flagged
photo string/null Firebase Storage URL of evidence photo

Problem Reporting

Controller: ProblemSectionController Service: ImageService for camera capture

When a package has issues:

  1. User selects problem type (No Name, No Address, Damaged, etc.)
  2. Optionally captures photo via device camera
  3. Photo uploaded to Firebase Storage
  4. Problem type and photo URL stored in scan history entry

Bad Scan Reporting

A separate “Report Bad Scan” dialog allows users to flag incorrect barcode scans. This creates a webLogs entry with isBadScan: true, which triggers the badScanAlert cloud function to email administrators.