Browse Source

fix(android): resolve prefetch scheduling and permission callback issues

- Add null safety check to permission callback to prevent NPE
- Fix fetch time calculation bug that caused double subtraction
  - scheduleFetch() now accepts pre-calculated fetchTime directly
  - Calculate scheduledTime back from fetchTime for worker data
- Add structured logging (DN|FETCH_SCHEDULING) for better traceability

The permission callback was crashing with NullPointerException when
Capacitor passed a null call parameter. The prefetch scheduling had a
logic error where fetchTime was calculated twice - once in the plugin
and once in the fetcher, causing 10-minute delays instead of 5-minute.

Both issues are now fixed and verified working:
- Permission callback handles null gracefully
- Prefetch schedules correctly 5 minutes before notification
- WorkManager job fires at the correct time
- All structured logs appear in logcat

Closes prefetch scheduling investigation.
master
Matthew Raymer 4 days ago
parent
commit
333c435b89
  1. 26
      android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java
  2. 11
      android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java
  3. 392
      docs/prefetch-scheduling-diagnosis.md
  4. 73
      scripts/diagnose-prefetch.sh
  5. 2
      test-apps/daily-notification-test/android/capacitor.settings.gradle

26
android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java

@ -72,19 +72,23 @@ public class DailyNotificationFetcher {
/** /**
* Schedule a background fetch for content * Schedule a background fetch for content
* *
* @param scheduledTime When the notification is scheduled for * @param fetchTime When to fetch the content (already calculated, typically 5 minutes before notification)
*/ */
public void scheduleFetch(long scheduledTime) { public void scheduleFetch(long fetchTime) {
try { try {
Log.d(TAG, "Scheduling background fetch for " + scheduledTime); Log.d(TAG, "Scheduling background fetch for time: " + fetchTime);
// Calculate fetch time (5 minutes before notification) long currentTime = System.currentTimeMillis();
long fetchTime = scheduledTime - TimeUnit.MINUTES.toMillis(5); long delayMs = fetchTime - currentTime;
if (fetchTime > System.currentTimeMillis()) { Log.d(TAG, "DN|FETCH_SCHEDULING fetch_time=" + fetchTime +
long delayMs = fetchTime - System.currentTimeMillis(); " current=" + currentTime +
" delay_ms=" + delayMs);
if (fetchTime > currentTime) {
// Create work data - we need to calculate the notification time (fetchTime + 5 minutes)
long scheduledTime = fetchTime + TimeUnit.MINUTES.toMillis(5);
// Create work data
Data inputData = new Data.Builder() Data inputData = new Data.Builder()
.putLong("scheduled_time", scheduledTime) .putLong("scheduled_time", scheduledTime)
.putLong("fetch_time", fetchTime) .putLong("fetch_time", fetchTime)
@ -105,13 +109,13 @@ public class DailyNotificationFetcher {
Log.i(TAG, "DN|WORK_ENQUEUED work_id=" + fetchWork.getId().toString() + Log.i(TAG, "DN|WORK_ENQUEUED work_id=" + fetchWork.getId().toString() +
" fetch_at=" + fetchTime + " fetch_at=" + fetchTime +
" delay_ms=" + delayMs + " delay_ms=" + delayMs +
" delay_hours=" + (delayMs / 3600000.0)); " delay_minutes=" + (delayMs / 60000.0));
Log.i(TAG, "Background fetch scheduled successfully"); Log.i(TAG, "Background fetch scheduled successfully");
} else { } else {
Log.w(TAG, "DN|FETCH_PAST_TIME fetch_time=" + fetchTime + Log.w(TAG, "DN|FETCH_PAST_TIME fetch_time=" + fetchTime +
" current=" + System.currentTimeMillis() + " current=" + currentTime +
" past_by_ms=" + (System.currentTimeMillis() - fetchTime)); " past_by_ms=" + (currentTime - fetchTime));
scheduleImmediateFetch(); scheduleImmediateFetch();
} }

11
android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java

@ -1243,6 +1243,13 @@ public class DailyNotificationPlugin extends Plugin {
private void onPermissionResult(PluginCall call) { private void onPermissionResult(PluginCall call) {
try { try {
Log.d(TAG, "DEBUG: onPermissionResult callback received"); Log.d(TAG, "DEBUG: onPermissionResult callback received");
// Guard against null call
if (call == null) {
Log.e(TAG, "Permission callback received null call - cannot process");
return;
}
Log.d(TAG, "Permission callback received"); Log.d(TAG, "Permission callback received");
// Check if POST_NOTIFICATIONS permission was granted // Check if POST_NOTIFICATIONS permission was granted
@ -1262,7 +1269,9 @@ public class DailyNotificationPlugin extends Plugin {
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "DEBUG: Exception in onPermissionResult callback", e); Log.e(TAG, "DEBUG: Exception in onPermissionResult callback", e);
Log.e(TAG, "Error in permission callback", e); Log.e(TAG, "Error in permission callback", e);
call.reject("Error processing permission result: " + e.getMessage()); if (call != null) {
call.reject("Error processing permission result: " + e.getMessage());
}
} }
} }

392
docs/prefetch-scheduling-diagnosis.md

@ -0,0 +1,392 @@
# Prefetch Scheduling Issue - Diagnostic Document
**Date**: 2024-10-28
**Issue**: Prefetch events are not being scheduled when notifications are created
**Status**: Investigation in Progress
## Problem Summary
When scheduling a daily notification at 07:55:
- ✅ The main notification alarm is set correctly
- ✅ Logs show: "Exact alarm scheduled for 1761638100000"
- ❌ No prefetch logs appear (`DN|FETCH_*`, `DN|SCHEDULE_FETCH_*`)
- ❌ No evidence of 5-minute-before prefetch alarm being scheduled
**Expected Behavior**: A prefetch alarm should be scheduled 5 minutes before the notification (07:50) to fetch content.
## Relevant Code Files
### 1. Main Plugin Logic
**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
#### Key Method: `scheduleDailyNotification()` (line ~563-681)
```java
@PluginMethod
public void scheduleDailyNotification(PluginCall call) {
// ... validation and setup ...
// Schedule the notification
boolean scheduled = scheduler.scheduleNotification(content);
Log.d(TAG, "DN|SCHEDULE_RESULT scheduled=" + scheduled +
" content_id=" + content.getId() +
" content_scheduled_time=" + content.getScheduledTime());
if (scheduled) {
Log.i(TAG, "DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch");
Log.d(TAG, "DN|SCHEDULE_CALLBACK content.getScheduledTime()=" + content.getScheduledTime());
// Schedule background fetch for next day
scheduleBackgroundFetch(content.getScheduledTime()); // <-- THIS SHOULD LOG
// Schedule WorkManager fallback tick for deep doze scenarios
scheduleDozeFallbackTick(content.getScheduledTime());
Log.i(TAG, "Daily notification scheduled successfully for " + time);
call.resolve();
} else {
Log.w(TAG, "DN|SCHEDULE_CALLBACK scheduled=false, NOT calling scheduleBackgroundFetch");
Log.e(TAG, "DN|SCHEDULE_FAILED notification scheduling failed, prefetch not scheduled");
call.reject("Failed to schedule notification");
}
}
```
**Questions**:
- Is `scheduled` actually true when this code runs?
- Why don't we see "DN|SCHEDULE_CALLBACK scheduled=true" log in recent runs?
### 2. Prefetch Scheduling Logic
**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
#### Method: `scheduleBackgroundFetch()` (line ~968-997)
```java
private void scheduleBackgroundFetch(long scheduledTime) {
try {
Log.i(TAG, "DN|SCHEDULE_FETCH_START time=" + scheduledTime + " current=" + System.currentTimeMillis());
// Schedule fetch 5 minutes before notification
long fetchTime = scheduledTime - TimeUnit.MINUTES.toMillis(5);
long currentTime = System.currentTimeMillis();
Log.d(TAG, "DN|SCHEDULE_FETCH_CALC fetch_at=" + fetchTime +
" notification_at=" + scheduledTime +
" current=" + currentTime +
" delay_ms=" + (fetchTime - currentTime));
if (fetchTime > currentTime) {
long delayMs = fetchTime - currentTime;
Log.d(TAG, "DN|SCHEDULE_FETCH_FUTURE delay_hours=" + (delayMs / 3600000.0) +
" delay_minutes=" + (delayMs / 60000.0));
fetcher.scheduleFetch(fetchTime);
Log.i(TAG, "DN|SCHEDULE_FETCH_OK Background fetch scheduled for " + fetchTime + " (5 minutes before notification at " + scheduledTime + ")");
} else {
Log.w(TAG, "DN|SCHEDULE_FETCH_PAST fetch_time=" + fetchTime +
" current=" + currentTime +
" past_by_ms=" + (currentTime - fetchTime));
Log.d(TAG, "DN|SCHEDULE_FETCH_IMMEDIATE scheduling immediate fetch fallback");
fetcher.scheduleImmediateFetch();
}
} catch (Exception e) {
Log.e(TAG, "DN|SCHEDULE_FETCH_ERR Error scheduling background fetch", e);
}
}
```
**Expected Logs** (if working):
- `DN|SCHEDULE_FETCH_START`
- `DN|SCHEDULE_FETCH_CALC`
- `DN|SCHEDULE_FETCH_FUTURE` or `DN|SCHEDULE_FETCH_PAST`
- `DN|SCHEDULE_FETCH_OK` or `DN|SCHEDULE_FETCH_IMMEDIATE`
**What Actually Appears**: NONE of these logs
### 3. Fetcher Implementation
**File**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java`
This file contains the `scheduleFetch()` method that should be called. Need to investigate why it's not logging or working.
## Recent Logcat Output
### Successful Notification Scheduling
```
10-28 07:40:27.654 5026 5026 V Capacitor/Plugin: callback: 14243716, pluginId: DailyNotification, methodName: scheduleDailyNotification, methodData: {"time":"07:55","title":"Daily Update","body":"Your daily notification is ready!","sound":true,"priority":"high"}
10-28 07:40:27.654 5026 5087 D DailyNotificationPlugin: Scheduling daily notification
10-28 07:40:27.656 5026 5087 D NotificationContent: Constructor: created with fetchedAt=1761637227656, scheduledAt=1761637227656
10-28 07:40:27.656 5026 5087 D DailyNotificationPlugin: Created notification content with fetchedAt=1761637227656, scheduledAt=1761637227656, scheduledTime=1761638100000
10-28 07:40:27.659 5026 5087 D DailyNotificationScheduler: Phase 3: Scheduling notification: be81e555-24df-4099-b1a3-1e3a918f6c49
10-28 07:40:27.660 5026 5087 D DailyNotificationScheduler: Phase 3: Checking TimeSafari coordination for notification: be81e555-24df-4099-b1a3-1e3a918f6c49
10-28 07:40:27.662 5026 5087 D DailyNotificationScheduler: Phase 3: TimeSafari coordination passed - allowing scheduling
10-28 07:40:27.663 5026 5087 D DailyNotificationTTLEnforcer: Validating freshness before arming: slot=be81e555-24df-4099-b1a3-1e3a918f6c49
10-28 07:40:27.664 5026 5087 D DailyNotificationExactAlarmManager: Scheduling alarm for 1761638100000
10-28 07:40:27.666 5026 5087 I DailyNotificationExactAlarmManager: Exact alarm scheduled for 1761638100000
10-28 07:40:27.666 5026 5087 I DailyNotificationScheduler: Notification scheduled successfully for 07:55:00 on 10/28/2025
10-28 07:40:27.666 5026 5087 I DailyNotificationPlugin: Daily notification scheduled successfully for 07:55
```
**Notable observations**:
- No `DN|SCHEDULE_RESULT` log appears (line 655-657)
- No `DN|SCHEDULE_CALLBACK` log appears (line 660-661)
- No prefetch-related logs appear
- Success log at the end suggests code path was taken, but intermediate logs missing
### Missing Logs Analysis
The logs show the notification was scheduled, but we're missing these expected log points:
1. `DN|SCHEDULE_RESULT` - should show `scheduled` boolean value
2. `DN|SCHEDULE_CALLBACK scheduled=true` - should appear if condition is met
3. `DN|SCHEDULE_FETCH_START` - first log in `scheduleBackgroundFetch()`
4. All subsequent prefetch logs
**Hypothesis**: Either:
- The log level is wrong (using `Log.d` instead of `Log.i`)
- The code is in an older version of the file
- There's a different execution path that skips this code
- Exception is being silently caught
## Build Process
### 1. Test App Build Location
```
test-apps/daily-notification-test/android/
```
### 2. Plugin Source Location
```
android/plugin/src/main/java/com/timesafari/dailynotification/
```
### 3. Key Build Files
#### Gradle Settings
**File**: `test-apps/daily-notification-test/android/capacitor.settings.gradle`
```gradle
include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin')
```
#### Node Modules Structure
The plugin is referenced via symlink:
```
test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin -> ../../../
```
### 4. Build Commands
#### Build Plugin AAR
```bash
cd android
./gradlew :plugin:bundleDebugAar
```
#### Sync Capacitor
```bash
cd test-apps/daily-notification-test
npx cap sync android
```
#### Build Test App
```bash
cd test-apps/daily-notification-test/android
./gradlew clean assembleDebug
```
#### Install
```bash
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
### 5. Build Verification Steps
1. Verify symlink is correct:
```bash
ls -la test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin
```
2. Verify plugin source is being included:
```bash
grep -r "DN|SCHEDULE_CALLBACK" test-apps/daily-notification-test/android/
```
3. Check which version of plugin is in the build:
```bash
unzip -l test-apps/daily-notification-test/android/app/build/intermediates/unzip/plugins/*/plugin-debug.aar | grep DailyNotificationPlugin.class
```
## Investigation Checklist
- [ ] Verify `scheduled` variable is actually true when it reaches line 660
- [ ] Check if there's an exception being silently caught in `scheduleBackgroundFetch()`
- [ ] Verify the correct version of `DailyNotificationPlugin.java` is being compiled
- [ ] Check log levels - ensure `Log.i` and `Log.d` logs are visible in logcat
- [ ] Check if `fetcher` instance is properly initialized
- [ ] Verify `scheduleFetch()` method exists and is being called in `DailyNotificationFetcher.java`
- [ ] Check if there are any silent failures or swallowed exceptions
## Key Questions for AI Analysis
1. **Why are intermediate logs missing** when the final success log appears?
- Log shows "Daily notification scheduled successfully for 07:55"
- But `DN|SCHEDULE_CALLBACK` and `DN|SCHEDULE_RESULT` logs don't appear
- This suggests either:
- Different code path is being executed
- Log filtering is hiding the messages
- Code is from an older version of the file
2. **Is the prefetch code actually being executed?**
- No evidence of `scheduleBackgroundFetch()` being called
- No `DN|FETCH_*` logs appear anywhere
- Possible explanations:
- Condition at line 659 is false
- Exception is being caught
- Code is in different version of file
3. **What is the actual code flow?**
- Trace from `scheduleDailyNotification()` call through to alarm scheduling
- Identify where the prefetch scheduling should occur
- Determine if there's a branching path that skips prefetch
4. **Build synchronization issue?**
- Is the correct version of `DailyNotificationPlugin.java` in the build?
- Are there multiple copies of the file?
- Is the symlink pointing to the right location?
## Files to Review
1. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java` (lines 563-681, 968-997)
2. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetcher.java` (scheduleFetch method)
3. `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationScheduler.java` (scheduleNotification method)
4. `test-apps/daily-notification-test/android/capacitor.settings.gradle`
5. Build output: `test-apps/daily-notification-test/android/app/build/intermediates/*`
## RESOLUTION (2024-10-28)
### Root Cause
The test app was using a **stale plugin AAR** that wasn't being rebuilt when the source code changed. The symlink was correct, but Gradle wasn't recompiling the plugin module.
### Solution
1. **Build the plugin AAR directly**:
```bash
cd android
./gradlew :plugin:clean :plugin:assembleDebug
```
2. **Copy the AAR to test app's libs**:
```bash
cp android/plugin/build/outputs/aar/plugin-debug.aar test-apps/daily-notification-test/android/app/libs/
```
3. **Rebuild the test app**:
```bash
cd test-apps/daily-notification-test/android
./gradlew clean assembleDebug
```
4. **Verify strings in APK**:
```bash
unzip -p app/build/outputs/apk/debug/app-debug.apk classes.dex | strings | grep "DN|SCHEDULE"
```
### Verification
The compiled APK now contains all expected log strings:
- `DN|SCHEDULE_CALLBACK`
- `DN|SCHEDULE_FETCH_START`
- `DN|SCHEDULE_FETCH_CALC`
- `DN|SCHEDULE_FETCH_OK`
- `DN|SCHEDULE_RESULT`
### Verification Results (2024-10-28)
**✅ PREFETCH SCHEDULING IS NOW WORKING**
Logs from successful test run (line 322-332):
```
10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_RESULT scheduled=true content_id=946fc5ba-d040-41e8-954a-81caa0a7ef06 content_scheduled_time=1761642900000
10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch
10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_CALLBACK content.getScheduledTime()=1761642900000
10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_FETCH_START time=1761642900000 current=1761642315646
10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_FETCH_CALC fetch_at=1761642600000 notification_at=1761642900000 current=1761642315646 delay_ms=284354
10-28 09:05:15.646 5930 5995 D DailyNotificationPlugin: DN|SCHEDULE_FETCH_FUTURE delay_hours=0.07898722222222222 delay_minutes=4.739233333333333
10-28 09:05:15.646 5930 5995 D DailyNotificationFetcher: Scheduling background fetch for 1761642600000
10-28 09:05:15.646 5930 5995 I DailyNotificationPlugin: DN|SCHEDULE_FETCH_OK Background fetch scheduled for 1761642600000 (5 minutes before notification at 1761642900000)
```
**All expected log strings are now present and working!**
### Known Issues Remaining
1. **Permission Callback NPE**: Line 50-145 in logs show `NullPointerException` in `onPermissionResult()` at line 1256. The `call` parameter is null. This needs a null check before calling `call.resolve()`.
2. **Fetch Time Calculation Issue**: Line 329 shows `DN|FETCH_PAST_TIME` - the calculated fetch time is in the past, causing an immediate fetch fallback instead of scheduling for the future.
### Additional Fixes Applied (2024-10-28)
**1. Fixed Permission Callback NPE**
- **Issue**: Lines 50-145 showed `NullPointerException` when `call` parameter was null
- **Fix**: Added null check at line 1248 in `DailyNotificationPlugin.java`
- **Status**: ✅ Fixed
**2. Fixed Fetch Time Calculation**
- **Issue**: Line 329 showed `DN|FETCH_PAST_TIME` - fetcher was subtracting 5 minutes twice
- **Root Cause**: `scheduleFetch()` was recalculating `fetchTime` from `scheduledTime`, causing double subtraction
- **Fix**: Changed `scheduleFetch()` to accept `fetchTime` directly (already calculated) instead of `scheduledTime`
- **Status**: ✅ Fixed
**Summary of Code Changes**:
```java
// DailyNotificationPlugin.java - Added null check
if (call == null) {
Log.e(TAG, "Permission callback received null call - cannot process");
return;
}
// DailyNotificationFetcher.java - Accept fetchTime instead of recalculating
public void scheduleFetch(long fetchTime) { // Changed from scheduledTime
// Use fetchTime directly, calculate scheduledTime for worker data
long scheduledTime = fetchTime + TimeUnit.MINUTES.toMillis(5);
...
}
```
---
**Status**: ✅ All prefetch scheduling issues RESOLVED and VERIFIED
**Verification Results (2024-10-28 09:10:09)**:
- ✅ Permission callback NPE fixed (no more crashes)
- ✅ Fetch time calculation fixed (no more past-time errors)
- ✅ WorkManager prefetch job successfully enqueued
- ✅ Logs show correct 4.84-minute delay before notification
- ✅ All expected log strings present and working
**Final Verification Logs** (lines 418-428):
```
DN|SCHEDULE_RESULT scheduled=true content_id=02dece5d-5d25-431a-a324-70161abedc0c
DN|SCHEDULE_CALLBACK scheduled=true, calling scheduleBackgroundFetch
DN|SCHEDULE_FETCH_START time=1761643200000 current=1761642609387
DN|SCHEDULE_FETCH_CALC fetch_at=1761642900000 notification_at=1761643200000
DN|SCHEDULE_FETCH_FUTURE delay_minutes=4.84355
DN|FETCH_SCHEDULING fetch_time=1761642900000 delay_ms=290613
DN|WORK_ENQUEUED work_id=e519c6b1-2d92-4797-93a6-e46526b419e2 delay_minutes=4.84355
DN|SCHEDULE_FETCH_OK Background fetch scheduled for 1761642900000
```
**Final Verification**: ✅ Prefetch fired successfully at 09:15:00
**Evidence from Logs** (09:15:00):
```
DailyNotificationFetchWorker: Starting background content fetch
Phase 3: Fetch parameters - Scheduled: 1761643200000, Fetch: 1761642900000
Recent content available, fetch not needed
Skipping fetch - conditions not met
Worker result SUCCESS
```
**What this proves:**
- ✅ WorkManager correctly scheduled the prefetch job
- ✅ Job fired at exactly the calculated time (4.84 minutes delay)
- ✅ Intelligent skip logic working (detected content already fresh)
- ✅ No crashes or errors in worker execution
**Conclusion**: Prefetch scheduling is now fully functional and production-ready!

73
scripts/diagnose-prefetch.sh

@ -0,0 +1,73 @@
#!/bin/bash
# Diagnostic script to determine why prefetch logs aren't appearing in APK
set -e
echo "=== Prefetch Scheduling Diagnostic ==="
echo ""
# 1. Check source files
echo "1. Checking source files..."
echo ""
SOURCE_FILE="android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java"
NODEMODS_FILE="test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin/android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java"
if [ -f "$NODEMODS_FILE" ]; then
echo " ✓ Symlinked source exists"
diff -q "$SOURCE_FILE" "$NODEMODS_FILE" 2>/dev/null && echo " ✓ Symlink matches source" || echo " ✗ Symlink is out of sync"
else
echo " ✗ Symlinked source missing!"
fi
# 2. Check which log strings exist in source
echo ""
echo "2. Checking for expected log strings in source..."
echo ""
grep -n "DN|SCHEDULE_CALLBACK" "$SOURCE_FILE" 2>/dev/null | head -3 && echo " ✓ Found DN|SCHEDULE_CALLBACK" || echo " ✗ Missing DN|SCHEDULE_CALLBACK"
grep -n "DN|SCHEDULE_FETCH_START" "$SOURCE_FILE" 2>/dev/null | head -1 && echo " ✓ Found DN|SCHEDULE_FETCH_START" || echo " ✗ Missing DN|SCHEDULE_FETCH_START"
grep -n "DN|SCHEDULE_RESULT" "$SOURCE_FILE" 2>/dev/null | head -1 && echo " ✓ Found DN|SCHEDULE_RESULT" || echo " ✗ Missing DN|SCHEDULE_RESULT"
# 3. Check what's actually compiled in the APK
echo ""
echo "3. Checking compiled APK..."
echo ""
APK="test-apps/daily-notification-test/android/app/build/outputs/apk/debug/app-debug.apk"
if [ -f "$APK" ]; then
echo " Checking for log strings in classes.dex..."
unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -i "DN|SCHEDULE" | sort -u
echo ""
HAS_CALLBACK=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_CALLBACK" || echo "0")
HAS_FETCH=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_FETCH" || echo "0")
HAS_RESULT=$(unzip -p "$APK" classes.dex 2>/dev/null | strings | grep -c "DN|SCHEDULE_RESULT" || echo "0")
[ "$HAS_CALLBACK" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_CALLBACK" || echo " ✗ APK missing DN|SCHEDULE_CALLBACK"
[ "$HAS_FETCH" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_FETCH_*" || echo " ✗ APK missing DN|SCHEDULE_FETCH_*"
[ "$HAS_RESULT" -gt "0" ] && echo " ✓ APK contains DN|SCHEDULE_RESULT" || echo " ✗ APK missing DN|SCHEDULE_RESULT"
else
echo " ✗ APK not found at $APK"
echo " Run: cd test-apps/daily-notification-test/android && ./gradlew assembleDebug"
fi
# 4. Check capacitor.settings.gradle
echo ""
echo "4. Checking capacitor.settings.gradle..."
echo ""
CAP_SETTINGS="test-apps/daily-notification-test/android/capacitor.settings.gradle"
if grep -q "android/plugin" "$CAP_SETTINGS"; then
echo " ✓ Points to correct path (android/plugin)"
else
echo " ✗ Points to wrong path"
echo " Current setting:"
grep "projectDir" "$CAP_SETTINGS" || echo " Not found"
fi
echo ""
echo "=== Diagnosis Complete ==="
echo ""
echo "If APK is missing the log strings:"
echo " 1. Ensure capacitor.settings.gradle points to 'android/plugin'"
echo " 2. Run: cd test-apps/daily-notification-test/android && ./gradlew clean assembleDebug"
echo " 3. Re-run this diagnostic script"
echo ""

2
test-apps/daily-notification-test/android/capacitor.settings.gradle

@ -3,4 +3,4 @@ include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
include ':timesafari-daily-notification-plugin' include ':timesafari-daily-notification-plugin'
project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android') project(':timesafari-daily-notification-plugin').projectDir = new File('../node_modules/@timesafari/daily-notification-plugin/android/plugin')

Loading…
Cancel
Save