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
- User taps SCAN button on Home Page
CustomScannerdialog opens with camera preview- Scanner detects barcode within the scan window
- Raw barcode string is extracted
LogisticService.identifyCourier(barcode)identifies the carrier- Display tracking number is extracted (carrier-specific logic)
PackageCheckServicequeries Firestore to see if package exists- App navigates to Check-In or Package Details screen
- 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:
- Query by
trackingNumberfield (exact match) - Carrier-specific secondary queries (e.g., last 12/22 chars for USPS/FedEx)
- Returns
PackageCheckResultwith:- 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:
- User selects problem type (No Name, No Address, Damaged, etc.)
- Optionally captures photo via device camera
- Photo uploaded to Firebase Storage
- 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.