Advanced Configuration
This guide covers advanced configuration options for the GOFA WebView SDK.
Highlights
- Flexible callback configuration for WebView events
- Environment-based configuration using helper classes and environment variables
- Secure authentication with client credentials and optional basic auth
- Customizable navigation URLs for different GOFA services
- Support for custom headers
- Build-time and runtime configuration via Dart defines
- Configuration validation with clear error handling
- Troubleshooting tips and configuration best practices
Callback Configuration
When embedding the GOFA web app in your Flutter app using the WebView SDK, the web app communicates important events back to Flutter via the updateCallback function you provide to WebViewSdkManager.
The web app posts messages using the postMessage API. The Flutter SDK receives these messages and invokes your updateCallback with the event name and event data.
Basic Event Handler Setup
final webViewSdkManager = WebViewSdkManager(
environment: Environment.DEV,
updateCallback: (String eventName, dynamic eventData) {
// Handle different event types
switch (eventName) {
case 'START_ASSESSMENT':
// Handle assessment initiation
_handleAssessmentStart(eventData);
break;
case 'FINISH_ASSESSMENT':
// Handle assessment completion
_handleAssessmentFinish(eventData);
break;
case 'GENERATED_REPORT':
// Handle report generation
_handleReportGenerated(eventData);
break;
case 'EARLY_QUIT':
// Handle early exit scenarios
_handleEarlyQuit(eventData);
break;
default:
print('Unknown event: $eventName');
}
},
);
Tip: The
updateCallbackreceives the event name and a data map. You can use this to trigger navigation, analytics, or other business logic in your Flutter app.
For specific event types and data structures for different GOFA modules (such as MSK assessments), refer to the respective integration guides:
- MSK Integration Guide - Complete MSK event handling
Event Data Structure
Most events follow a consistent data structure pattern:
// Common event data fields
{
'eventId': 'unique-event-identifier',
'timestamp': 'iso-date-string',
'userId': 'user-identifier',
'moduleType': 'msk|wellness|other',
// Additional event-specific data
}
Environment Helper Class
Create a helper class for environment-specific configuration:
class EnvironmentConfig {
static const String environment = String.fromEnvironment('GOFA_ENVIRONMENT', defaultValue: 'DEV');
static const String clientId = String.fromEnvironment('GOFA_CLIENT_ID');
static const String clientSecret = String.fromEnvironment('GOFA_CLIENT_SECRET');
static const String clientUserId = String.fromEnvironment('GOFA_CLIENT_USER_ID');
static bool get isProduction => environment == 'PRD';
static String get baseUrl {
switch (environment) {
case 'PRD': return 'https://client.gofa.app';
case 'UAT': return 'https://client-uat.uat.gofa.app';
default: return 'https://client-dev.dev.gofa.app';
}
}
}
URL Examples
Navigator.pushNamed(
context,
GofaWebView.routeName,
arguments: {
// MSK (Musculoskeletal) services
'url': 'https://bupa-uat.uat.gofa.app/msk/home',
'clientId': clientId,
'locale': const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
),
},
);
Authentication Configuration
Client Credentials
Configure your application's authentication credentials:
const clientId = String.fromEnvironment('GOFA_CLIENT_ID', defaultValue: 'your-client-id');
const clientSecret = String.fromEnvironment('GOFA_CLIENT_SECRET', defaultValue: 'your-client-secret');
const clientUserId = String.fromEnvironment('GOFA_CLIENT_USER_ID', defaultValue: 'unique-user-id');
Basic Authentication
For additional security on certain resources:
final webViewSdkManager = WebViewSdkManager(
environment: environment,
basicAuthUser: 'gofa', // Username for basic auth
basicAuthPass: 'your-secure-password', // Password for basic auth
);
HTTP Basic Authentication
Custom Headers
You can configure custom headers for WebView requests:
// The SDK automatically handles authentication headers
// Custom headers can be added through the initialization process
webViewSdkManager.init(
clientId: clientId,
clientSecret: clientSecret,
clientUserId: clientUserId,
environment: environment,
basicAuthUser: basicAuthUser,
basicAuthPass: basicAuthPass,
);
Runtime Configuration
Environment Variables
Set up environment variables for different build configurations:
# Development build
flutter build apk --dart-define=GOFA_ENVIRONMENT=DEV \
--dart-define=GOFA_CLIENT_ID=dev-client-id \
--dart-define=GOFA_CLIENT_SECRET=dev-secret
# UAT build
flutter build apk --dart-define=GOFA_ENVIRONMENT=UAT \
--dart-define=GOFA_CLIENT_ID=uat-client-id \
--dart-define=GOFA_CLIENT_SECRET=uat-secret
# Production build
flutter build apk --dart-define=GOFA_ENVIRONMENT=PRD \
--dart-define=GOFA_CLIENT_ID=prod-client-id \
--dart-define=GOFA_CLIENT_SECRET=prod-secret
Configuration Validation
Validation Function
Create a validation function to ensure proper configuration:
class ConfigValidator {
static Future<bool> validateConfiguration() async {
// Check environment
if (!['DEV', 'UAT', 'PRD'].contains(EnvironmentConfig.environment)) {
print('❌ Invalid environment: {EnvironmentConfig.environment}');
return false;
}
// Check required credentials
if (EnvironmentConfig.clientId.isEmpty) {
print('❌ CLIENT_ID is required');
return false;
}
if (EnvironmentConfig.clientSecret.isEmpty) {
print('❌ CLIENT_SECRET is required');
return false;
}
if (EnvironmentConfig.clientUserId.isEmpty) {
print('❌ CLIENT_USER_ID is required');
return false;
}
// Validate production settings
if (EnvironmentConfig.isProduction) {
if (EnvironmentConfig.clientId == 'abc' ||
EnvironmentConfig.clientSecret == 'abcSecret') {
print('❌ Cannot use default credentials in production');
return false;
}
}
print('✅ Configuration validation passed');
return true;
}
}
// Use in your app initialization
void main() async {
WidgetsFlutterBinding.ensureInitialized();
if (await ConfigValidator.validateConfiguration()) {
runApp(const MyApp());
} else {
runApp(const ConfigErrorApp());
}
}
Troubleshooting & Best Practices
- Use environment variables for all sensitive configuration
- Validate configuration before app initialization
- Use different credentials for each environment
- Never hardcode production credentials in source code
- Test configuration changes in development first
- If you encounter authentication or network issues, double-check your environment and credentials
- Ensure all required parameters are provided during SDK initialization
Next Steps
- SDK Reference: Complete API documentation