This guide covers advanced configuration options for the GOFA WebView SDK.
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.
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.
Event Details
For specific event types and data structures for different GOFA modules (such as MSK assessments), refer to the respective integration guides:
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
}Create a helper class for environment-specific configuration:
class EnvironmentConfig {
static const String _envString = 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');
/// Converts the GOFA_ENVIRONMENT string to the SDK enum.
static Environment get environment {
switch (_envString.toUpperCase()) {
case 'PRD': return Environment.PRD;
case 'UAT': return Environment.UAT;
default: return Environment.DEV;
}
}
static bool get isProduction => environment == Environment.PRD;
static String get baseUrl {
switch (environment) {
case Environment.PRD: return 'https://client.gofa.app';
case Environment.UAT: return 'https://client.uat.gofa.app';
default: return 'https://client.dev.gofa.app';
}
}
}Route Registration Required
If you navigate with Navigator.pushNamed(..., GofaWebView.routeName, ...), ensure GofaWebView.routeName is registered in your app's MaterialApp.routes first.
Navigator.pushNamed(
context,
GofaWebView.routeName,
arguments: {
// Example: MSK (Musculoskeletal) services
'url': 'https://your-client.gofa.app/msk/home',
'clientId': clientId,
'locale': const Locale.fromSubtags(
languageCode: 'zh',
scriptCode: 'Hant',
),
},
);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');Deprecated — Removed in v1.1.0
HTTP Basic Auth for MSK routes has been replaced by Firebase custom token authentication. The basicAuthUser and basicAuthPass parameters are deprecated and will be removed in a future version. You can safely omit them. See MSK Authentication for the current auth flow.
You can configure custom headers for WebView requests:
// The SDK automatically handles authentication headers
// Custom headers can be added through the initialization process
await webViewSdkManager.init(
clientId: clientId,
clientSecret: clientSecret,
clientUserId: clientUserId,
environment: EnvironmentConfig.environment,
);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-secretCreate a validation function to ensure proper configuration:
class ConfigValidator {
static Future<bool> validateConfiguration() async {
// Check environment
if (![Environment.DEV, Environment.UAT, Environment.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());
}
}Configuration Best Practices
| Date | Change |
|---|---|
| 2026-02-24 | Added route-registration prerequisite note for Navigator.pushNamed WebView navigation example. |
| 2026-02-13 | Updated EnvironmentConfig helper to use Environment enum. Fixed init() call to use await. |
| 2026-02-11 | Replaced Bupa-specific URL example with generic your-client.gofa.app placeholder. |
| 2026-02-11 | Deprecated Basic Authentication section. Removed basicAuthUser/basicAuthPass from code examples. MSK routes now use Firebase custom tokens. |