weebi_openfoodfacts_service 1.2.0
weebi_openfoodfacts_service: ^1.2.0 copied to clipboard
Advanced OpenFoodFacts integration with multi-language support, image caching, offline capabilities, and Open Prices integration for real-world pricing data.
Weebi OpenFoodFacts Service #
A comprehensive, reusable Flutter package for integrating with OpenFoodFacts API with advanced features like multi-language support, intelligent caching, and Open Prices integration for real-world pricing data.
๐ Features #
Current Capabilities #
- OpenFoodFacts Integration: Full access to 2.9M+ food products
- ๐ Open Prices Integration: Real-world pricing data from crowdsourced receipts
- Multi-Language Support: 10+ languages with automatic fallbacks
- Advanced Caching: Product and image caching for offline support
- ๐ Secure Credential Management: Automatic credential loading with .gitignore support
- Framework-Agnostic: Can be used in any Flutter project
- Production Ready: Comprehensive error handling and validation
๐งพ Open Prices Features #
- Real-time Pricing: Current prices from actual stores
- Price History: Track price changes over time
- Store Locations: Find products at specific stores
- Price Statistics: Average, min/max prices with trends
- Crowdsourced Data: Community-driven price validation
- Receipt Integration: Submit prices from receipts (with auth)
Architecture Foundation for Future Expansion #
- Multi-Database Ready: Built with extensibility for OpenBeautyFacts and OpenProductsFacts
- Product Type System: Supports food, beauty, and general product types
- Flexible Caching: Database-aware caching system
- Scalable Design: Easy to extend for new databases and features
๐ Current Database Support #
| Database | Products | Pricing | Status | Description |
|---|---|---|---|---|
| OpenFoodFacts | 2.9M+ | โ Yes | โ Active | Food products with nutrition + pricing data |
| OpenBeautyFacts | 19K+ | ๐ง Planned | ๐ง Planned | Cosmetic and beauty products |
| OpenProductsFacts | 11K+ | ๐ง Planned | ๐ Planned | General consumer products |
๐ฆ Installation #
Add this to your pubspec.yaml:
dependencies:
weebi_openfoodfacts_service:
git:
url: https://github.com/weebi-com/weebi_openfoodfacts.git
ref: main
๐ Credential Setup (For Price Submission) #
The service works in read-only mode without credentials. For price submission capabilities, follow these steps:
1. Create Your Credential File #
The service automatically looks for open_prices_credentials.json in your package root:
# In your project root, create the credential file:
touch open_prices_credentials.json
# Add it to .gitignore (IMPORTANT!)
echo "open_prices_credentials.json" >> .gitignore
2. Get Your Open Prices API Credentials #
- Visit: https://prices.openfoodfacts.org
- Create Account: Sign up for a free account
- Get API Token: Generate an API token in your account settings
- Note User ID: Copy your user ID from your profile
3. Configure Your Credentials #
Edit open_prices_credentials.json:
{
"_comment": "Open Prices API Credentials - Keep this file secure and in .gitignore",
"open_prices": {
"auth_token": "your_actual_auth_token_here",
"api_url": "https://prices.openfoodfacts.org/api/v1",
"user_id": "your_actual_user_id",
"app_name": "YourAppName/1.0"
}
}
4. Verify Setup #
import 'package:weebi_openfoodfacts_service/weebi_openfoodfacts_service.dart';
// Check credential status
final status = WeebiOpenFoodFactsService.getCredentialStatus();
print('Can submit prices: ${status['can_submit_prices']}'); // Should be true
// Test price submission
final success = await WeebiOpenFoodFactsService.submitPrice(
barcode: '3017620422003',
price: 3.45,
currency: 'EUR',
locationId: 'store_osm_id',
);
๐ File Structure #
your_project/
โโโ pubspec.yaml
โโโ .gitignore # MUST include credential files
โโโ open_prices_credentials.json # Your actual credentials (ignored by git)
โโโ open_prices_credentials.json.example # Safe template (can be committed)
โโโ lib/
โโโ your_app.dart
๐ Security Best Practices #
# โ
DO: Add credential files to .gitignore
echo "open_prices_credentials.json" >> .gitignore
echo "credentials.json" >> .gitignore
echo ".env" >> .gitignore
# โ
DO: Use different credentials for different environments
# Production: open_prices_credentials.json
# Development: open_prices_credentials.dev.json
# Testing: open_prices_credentials.test.json
# โ DON'T: Commit actual credentials to git
# โ DON'T: Hard-code credentials in source code
# โ DON'T: Share credential files via email/chat
๐ ๏ธ Quick Start #
1. Initialize the Service (Auto-loads Credentials) #
import 'package:weebi_openfoodfacts_service/weebi_openfoodfacts_service.dart';
await WeebiOpenFoodFactsService.initialize(
appName: 'MyAwesomeApp',
appUrl: 'https://myapp.com', // Optional
preferredLanguages: [
WeebiLanguage.english,
WeebiLanguage.french,
WeebiLanguage.spanish,
],
cacheConfig: CacheConfig.production,
enablePricing: true, // ๐ Enable Open Prices integration
autoLoadCredentials: true, // ๐ Automatically load credentials from files
);
// Check what capabilities are available
final status = WeebiOpenFoodFactsService.getCredentialStatus();
print('Pricing enabled: ${status['pricing_enabled']}');
print('Can submit prices: ${status['can_submit_prices']}');
2. Get Product with Pricing Information #
// Get a food product with pricing data
final product = await WeebiOpenFoodFactsService.getProduct('3017620422003');
if (product != null) {
print('Product: ${product.name}');
print('Brand: ${product.brand}');
print('Nutri-Score: ${product.nutriScore}');
print('NOVA Group: ${product.novaGroup}');
// ๐ Pricing information
if (product.hasPriceData) {
print('Current Price: ${product.currentPrice}');
print('Price Stats: ${product.priceStats?.averagePrice} EUR avg');
print('Recent Prices: ${product.recentPrices.length} records');
}
}
3. Advanced Pricing Queries #
// Get latest price for a product
final latestPrice = await WeebiOpenFoodFactsService.getLatestPrice('3017620422003');
print('Latest: ${latestPrice?.price} ${latestPrice?.currency} at ${latestPrice?.storeName}');
// Get price history
final priceHistory = await WeebiOpenFoodFactsService.getPriceHistory(
'3017620422003',
limit: 30,
since: DateTime.now().subtract(Duration(days: 30)),
);
// Get price statistics
final stats = await WeebiOpenFoodFactsService.getPriceStats('3017620422003');
print('Average: ${stats?.averagePrice} EUR');
print('Range: ${stats?.minPrice} - ${stats?.maxPrice} EUR');
// Search products with prices in a location
final productsWithPrices = await WeebiOpenFoodFactsService.searchProductsWithPrices(
location: 'Paris',
limit: 20,
);
๐ Multi-Language Support #
The service automatically tries your preferred languages in order:
await WeebiOpenFoodFactsService.initialize(
appName: 'MyApp',
preferredLanguages: [
WeebiLanguage.french, // Try French first
WeebiLanguage.english, // Fallback to English
WeebiLanguage.spanish, // Then Spanish
],
);
Supported Languages:
- ๐บ๐ธ English
- ๐ซ๐ท French
- ๐ช๐ธ Spanish
- ๐ฉ๐ช German
- ๐ฎ๐น Italian
- ๐ต๐น Portuguese
- ๐ณ๐ฑ Dutch
- ๐จ๐ณ Chinese
- ๐ฏ๐ต Japanese
- ๐ธ๐ฆ Arabic
๐พ Caching System #
Cache Configurations #
// Production: Aggressive caching for performance
CacheConfig.production
// Development: Minimal caching for testing
CacheConfig.development
// Custom configuration
CacheConfig(
enableProductCache: true,
enableImageCache: true,
productCacheMaxAge: Duration(days: 7),
imageCacheMaxAge: Duration(days: 30),
maxCacheSize: 100 * 1024 * 1024, // 100MB
)
Cache Management #
// Clear all caches
await WeebiOpenFoodFactsService.clearCache();
// Get cache statistics
final stats = await WeebiOpenFoodFactsService.getCacheStats();
print('Cached products: ${stats['products']['count']}');
print('Cache size: ${stats['images']['size']} bytes');
๐๏ธ Product Types & Future Database Support #
The service is architected to support multiple product databases:
// Current: Food products (OpenFoodFacts) with pricing
final foodProduct = await WeebiOpenFoodFactsService.getFoodProduct('3017620422003');
print('Type: ${foodProduct.productType}'); // WeebiProductType.food
print('Price: ${foodProduct.currentPrice}'); // ๐ Real pricing data
// Future: Beauty products (OpenBeautyFacts) - Coming Soon
// final beautyProduct = await WeebiOpenFoodFactsService.getBeautyProduct('3560070791460');
// Future: General products (OpenProductsFacts) - Coming Soon
// final generalProduct = await WeebiOpenFoodFactsService.getGeneralProduct('1234567890123');
๐ Product Information Available #
Food Products (Current) #
- โ Basic Info: Name, brand, barcode
- โ Nutrition: Nutri-Score (A-E), NOVA group (1-4)
- โ Safety: Allergens, ingredients analysis
- โ Images: Front, ingredients, nutrition facts
- โ Multi-language: All data in preferred languages
- โ ๐ Pricing: Current prices, price history, statistics
Beauty Products (Planned) #
- ๐ง Basic Info: Name, brand, barcode
- ๐ง Cosmetic Data: Period after opening, ingredients
- ๐ง Safety: Allergen warnings, risk assessments
- ๐ง Images: Product photos, ingredient lists
- ๐ง ๐ Pricing: Beauty product pricing (future)
General Products (Planned) #
- ๐ง Basic Info: Name, brand, barcode, category
- ๐ง Product Data: Features, specifications
- ๐ง Images: Product photos, documentation
- ๐ง ๐ Pricing: General product pricing (future)
๐ง Advanced Usage #
Credential Management #
// Manual credential loading (if autoLoadCredentials = false)
final loaded = await WeebiOpenFoodFactsService.loadCredentials();
print('Credentials loaded: $loaded');
// Reload credentials after file changes
await WeebiOpenFoodFactsService.loadCredentials();
// Check credential status
final status = WeebiOpenFoodFactsService.getCredentialStatus();
print('Auth available: ${status['open_prices_auth_available']}');
// Manual token setting (overrides file-based credentials)
WeebiOpenFoodFactsService.setOpenPricesAuthToken('your_token');
Performance Optimization #
// Get product without pricing for faster response
final product = await WeebiOpenFoodFactsService.getProductBasic('3017620422003');
// Get product with pricing specifically
final productWithPricing = await WeebiOpenFoodFactsService.getProductWithPricing(
'3017620422003',
location: 'Paris', // Optional location filter
);
Error Handling #
try {
final product = await WeebiOpenFoodFactsService.getProduct('invalid-barcode');
} catch (e) {
if (e is StateError) {
// Service not initialized
print('Please initialize the service first');
} else {
// Network or other errors
print('Error fetching product: $e');
}
}
๐ Price Submission (Requires Authentication) #
// Submit a new price (requires credentials in open_prices_credentials.json)
final success = await WeebiOpenFoodFactsService.submitPrice(
barcode: '3017620422003',
price: 3.45,
currency: 'EUR',
locationId: 'store_osm_id',
proofUrl: 'https://example.com/receipt.jpg', // Optional
);
if (success) {
print('Price submitted successfully!');
} else {
print('Failed to submit price - check credentials');
}
Store Locations #
// Get available store locations
final locations = await WeebiOpenFoodFactsService.getStoreLocations();
for (final location in locations) {
print('${location['osm_display_name']} - ${location['osm_address_city']}');
}
// Check Open Prices API status
final status = await WeebiOpenFoodFactsService.getOpenPricesStatus();
print('API Status: ${status?['status']}');
๐ฏ Use Cases #
This package is perfect for:
- ๐ Point of Sale Systems: Product lookup with real-time pricing
- ๐ฑ Inventory Management: Track products with cost analysis
- ๐ฝ๏ธ Recipe Applications: Nutritional information + ingredient costs
- ๐ช E-commerce Platforms: Product data + competitive pricing
- ๐ Price Comparison Apps: Multi-store price tracking
- ๐ Smart Shopping Apps: Barcode scanning with price alerts
- ๐ฐ Budget Tracking: Food expense analysis with nutrition data
๐ Roadmap #
Phase 1: OpenFoodFacts + Open Prices (โ Complete) #
- โ Multi-language API integration
- โ Advanced caching system
- โ Comprehensive error handling
- โ ๐ Open Prices integration
- โ ๐ Real-time pricing data
- โ ๐ Price history & statistics
- โ ๐ Secure credential management
- โ Production-ready package
Phase 2: OpenBeautyFacts (๐ง In Progress) #
- โ Beauty product API integration
- โ Cosmetic-specific data fields
- โ Period after opening support
- โ Ingredient safety analysis
- โ ๐ Beauty product pricing
Phase 3: OpenProductsFacts (๐ Planned) #
- โ General product API integration
- โ Product category system
- โ Multi-database search
- โ Unified product interface
- โ ๐ General product pricing
Phase 4: Advanced Features (๐ฏ Future) #
- โ ๐ Price alerts & notifications
- โ ๐ Receipt scanning integration
- โ ๐ Store loyalty program integration
- โ Machine learning recommendations
- โ Custom taxonomy support
- โ Enterprise features
๐ค Contributing #
We welcome contributions! This package is designed to be:
- Extensible: Easy to add new databases
- Maintainable: Clean architecture and documentation
- Testable: Comprehensive test coverage
- Reusable: Framework-agnostic design
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
- OpenFoodFacts for the amazing open data
- ๐ Open Prices for crowdsourced pricing data
- OpenBeautyFacts for cosmetic product data
- OpenProductsFacts for general product data
- The Dart/Flutter community for excellent tooling
Built with โค๏ธ by Weebi for the Flutter community