fix(android): resolve SharedPreferences mismatch and document cross-platform storage pattern

- Fix TestNativeFetcher to read from same SharedPreferences as plugin
  - Changed PREFS_NAME from 'DailyNotificationPrefs' to 'daily_notification_timesafari'
  - Changed KEY_STARRED_PLAN_IDS from 'starred_plan_ids' to 'starredPlanIds'
  - Updated getStarredPlanIds() to read from plugin's SharedPreferences location
  - Added diagnostic logging for plan ID loading

- Add updateStarredPlans() call in App.vue mounted() hook
  - Ensures starred plan IDs are persisted to native storage on app startup
  - Allows native fetcher to read plan IDs from SharedPreferences
  - Added diagnostic logging for configuration flow

- Document cross-platform storage pattern
  - Created docs/CROSS_PLATFORM_STORAGE_PATTERN.md with architecture flow
  - Documented TypeScript → Capacitor bridge → Plugin → Native storage → Native fetcher flow
  - Added iOS implementation checklist with code examples
  - Clarified why native storage is needed (background workers can't use bridge)

- Add JWT generation logging to test-user-zero.ts
  - Log JWT algorithm (ES256K) and DID when token is generated
  - Helps diagnose JWT verification issues

Fixes:
- Empty planIds array in native fetcher requests
- SharedPreferences key mismatch between plugin and native fetcher
- Missing documentation for iOS implementation

All changes maintain backward compatibility.
This commit is contained in:
Matthew Raymer
2025-10-31 13:02:30 +00:00
parent d4bb902cbe
commit f256113ed9
4 changed files with 298 additions and 7 deletions

View File

@@ -50,9 +50,11 @@ public class TestNativeFetcher implements NativeNotificationContentFetcher {
private static final int RETRY_DELAY_MS = 1000; // Base delay for exponential backoff
// SharedPreferences constants
private static final String PREFS_NAME = "DailyNotificationPrefs";
private static final String KEY_STARRED_PLAN_IDS = "starred_plan_ids";
private static final String KEY_LAST_ACKED_JWT_ID = "last_acked_jwt_id";
// NOTE: Must match plugin's SharedPreferences name and keys for starred plans
// Plugin uses "daily_notification_timesafari" (see DailyNotificationPlugin.updateStarredPlans)
private static final String PREFS_NAME = "daily_notification_timesafari";
private static final String KEY_STARRED_PLAN_IDS = "starredPlanIds"; // Matches plugin key
private static final String KEY_LAST_ACKED_JWT_ID = "last_acked_jwt_id"; // Plugin doesn't use this yet
private final Gson gson = new Gson();
private final Context appContext;
@@ -304,12 +306,17 @@ public class TestNativeFetcher implements NativeNotificationContentFetcher {
*/
private List<String> getStarredPlanIds() {
try {
String idsJson = prefs.getString(KEY_STARRED_PLAN_IDS, "[]");
// Use the same SharedPreferences as the plugin (not the instance variable 'prefs')
// Plugin stores in "daily_notification_timesafari" with key "starredPlanIds"
SharedPreferences pluginPrefs = appContext.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
String idsJson = pluginPrefs.getString(KEY_STARRED_PLAN_IDS, "[]");
if (idsJson == null || idsJson.isEmpty() || idsJson.equals("[]")) {
Log.d(TAG, "TestNativeFetcher: No starred plan IDs found in SharedPreferences");
return new ArrayList<>();
}
// Parse JSON array
// Parse JSON array (plugin stores as JSON string)
JsonParser parser = new JsonParser();
JsonArray jsonArray = parser.parse(idsJson).getAsJsonArray();
List<String> planIds = new ArrayList<>();
@@ -318,11 +325,15 @@ public class TestNativeFetcher implements NativeNotificationContentFetcher {
planIds.add(jsonArray.get(i).getAsString());
}
Log.d(TAG, "TestNativeFetcher: Loaded " + planIds.size() + " starred plan IDs");
Log.i(TAG, "TestNativeFetcher: Loaded " + planIds.size() + " starred plan IDs from SharedPreferences");
if (planIds.size() > 0) {
Log.d(TAG, "TestNativeFetcher: First plan ID: " +
planIds.get(0).substring(0, Math.min(30, planIds.get(0).length())) + "...");
}
return planIds;
} catch (Exception e) {
Log.e(TAG, "TestNativeFetcher: Error loading starred plan IDs", e);
Log.e(TAG, "TestNativeFetcher: Error loading starred plan IDs from SharedPreferences", e);
return new ArrayList<>();
}
}