@ -145,6 +145,97 @@ public class DailyNotificationPlugin extends Plugin {
return nativeFetcher ;
}
/ * *
* Configure native fetcher with API credentials ( cross - platform method )
*
* < p > This plugin method receives configuration from TypeScript and passes it directly
* to the registered native fetcher implementation . This approach keeps the TypeScript
* interface cross - platform ( works on Android , iOS , and web ) without requiring
* platform - specific storage mechanisms . < / p >
*
* < p > < b > Usage Flow : < / b > < / p >
* < ol >
* < li > Host app registers native fetcher in { @code Application . onCreate ( ) } < / li >
* < li > TypeScript calls this method with API credentials < / li >
* < li > Plugin validates parameters and calls { @code nativeFetcher . configure ( ) } < / li >
* < li > Native fetcher stores configuration for use in { @code fetchContent ( ) } < / li >
* < / ol >
*
* < p > < b > When to call : < / b > < / p >
* < ul >
* < li > After app startup , once API credentials are available < / li >
* < li > After user login / authentication , when activeDid changes < / li >
* < li > When API server URL changes ( e . g . , switching between dev / staging / prod ) < / li >
* < / ul >
*
* < p > < b > Error Handling : < / b > < / p >
* < ul >
* < li > Rejects if required parameters are missing < / li >
* < li > Rejects if no native fetcher is registered < / li >
* < li > Returns error if native fetcher ' s { @code configure ( ) } throws exception < / li >
* < / ul >
*
* < p > < b > Example TypeScript Usage : < / b > < / p >
* < pre > { @code
* import { DailyNotification } from ' @capacitor - community / daily - notification ' ;
*
* await DailyNotification . configureNativeFetcher ( {
* apiBaseUrl : ' http : //10.0.2.2:3000',
* activeDid : ' did : ethr : 0x0000694B58C2cC69658993A90D3840C560f2F51F ' ,
* jwtSecret : ' test - jwt - secret - for - development '
* } ) ;
* } < / pre >
*
* @param call Plugin call containing configuration parameters :
* < ul >
* < li > { @code apiBaseUrl } ( required ) : Base URL for API server .
* Android emulator : "http://10.0.2.2:3000" ( maps to host localhost : 3000 ) .
* iOS simulator : "http://localhost:3000" .
* Production : "https://api.timesafari.com" < / li >
* < li > { @code activeDid } ( required ) : Active DID for authentication .
* Format : "did:ethr:0x..." < / li >
* < li > { @code jwtSecret } ( required ) : JWT secret for signing tokens .
* Keep secure in production . < / li >
* < / ul >
*
* @throws PluginException if configuration fails ( rejected via call . reject ( ) )
*
* @see NativeNotificationContentFetcher # configure ( String , String , String )
* /
@PluginMethod
public void configureNativeFetcher ( PluginCall call ) {
try {
String apiBaseUrl = call . getString ( "apiBaseUrl" ) ;
String activeDid = call . getString ( "activeDid" ) ;
String jwtSecret = call . getString ( "jwtSecret" ) ;
if ( apiBaseUrl = = null | | activeDid = = null | | jwtSecret = = null ) {
call . reject ( "Missing required parameters: apiBaseUrl, activeDid, and jwtSecret are required" ) ;
return ;
}
NativeNotificationContentFetcher fetcher = getNativeFetcher ( ) ;
if ( fetcher = = null ) {
call . reject ( "No native fetcher registered. Register one in Application.onCreate() before configuring." ) ;
return ;
}
Log . d ( TAG , "SPI: Configuring native fetcher - apiBaseUrl: " +
apiBaseUrl . substring ( 0 , Math . min ( 50 , apiBaseUrl . length ( ) ) ) +
"... activeDid: " + activeDid . substring ( 0 , Math . min ( 30 , activeDid . length ( ) ) ) + "..." ) ;
// Call configure on the native fetcher (defaults to no-op if not implemented)
fetcher . configure ( apiBaseUrl , activeDid , jwtSecret ) ;
Log . i ( TAG , "SPI: Native fetcher configured successfully" ) ;
call . resolve ( ) ;
} catch ( Exception e ) {
Log . e ( TAG , "SPI: Error configuring native fetcher" , e ) ;
call . reject ( "Failed to configure native fetcher: " + e . getMessage ( ) ) ;
}
}
/ * *
* Initialize the plugin and create notification channel
* /
@ -962,6 +1053,12 @@ public class DailyNotificationPlugin extends Plugin {
try {
Log . i ( TAG , "DN|SCHEDULE_FETCH_START time=" + scheduledTime + " current=" + System . currentTimeMillis ( ) ) ;
// Check if fetcher is initialized
if ( fetcher = = null ) {
Log . e ( TAG , "DN|SCHEDULE_FETCH_ERR fetcher is null - cannot schedule prefetch. Plugin may not be fully loaded." ) ;
return ;
}
// Schedule fetch 5 minutes before notification
long fetchTime = scheduledTime - TimeUnit . MINUTES . toMillis ( 5 ) ;
long currentTime = System . currentTimeMillis ( ) ;