Skip to content

Commit a4b538f

Browse files
author
AR Abdul Azeez
committed
updated the md file
1 parent 180a493 commit a4b538f

1 file changed

Lines changed: 75 additions & 22 deletions

File tree

Examples/OneSignalDemoV2/BUILDING_THE_APP.md

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ SMS operations:
4343
Tag operations:
4444
- addTag(key: String, value: String)
4545
- removeTag(key: String)
46-
- removeTags(keys: Collection<String>)
4746
- getTags(): Map<String, String>
4847
4948
Trigger operations:
5049
- addTrigger(key: String, value: String)
5150
- removeTrigger(key: String)
51+
- clearTriggers(keys: Collection<String>)
5252
5353
Outcome operations:
5454
- sendOutcome(name: String)
@@ -125,17 +125,17 @@ In MainViewModel.kt, implement observers:
125125

126126
### Section Order (top to bottom) - FINAL
127127

128-
1. **App Section** (App ID, Guidance Banner, Consent Toggle, Login/Logout)
129-
2. **Push Section** (Push ID, Enabled Toggle, Prompt Push button)
128+
1. **App Section** (App ID, Guidance Banner, Consent Toggle, Logged-in-as display, Login/Logout)
129+
2. **Push Section** (Push ID, Enabled Toggle, Auto-prompts permission on load)
130130
3. **Send Push Notification Section** (Simple, With Image, Custom buttons)
131131
4. **In-App Messaging Section** (Pause toggle)
132132
5. **Send In-App Message Section** (Top Banner, Bottom Banner, Center Modal, Full Screen)
133133
6. **Aliases Section** (RecyclerView with Add/Remove All)
134134
7. **Emails Section** (RecyclerView with Add, collapsible >5 items)
135135
8. **SMS Section** (RecyclerView with Add, collapsible >5 items)
136-
9. **Tags Section** (RecyclerView with Add/Remove All)
136+
9. **Tags Section** (RecyclerView with Add, individual remove only)
137137
10. **Outcome Events Section** (Send Outcome dropdown)
138-
11. **Triggers Section** (RecyclerView with Add - IN MEMORY ONLY)
138+
11. **Triggers Section** (RecyclerView with Add/Clear Triggers - IN MEMORY ONLY)
139139
12. **Track Event Section** (Track Event button)
140140
13. **Location Section** (Location Shared toggle, Prompt Location button)
141141
14. **Next Activity Button**
@@ -158,14 +158,17 @@ App Section layout:
158158
- SwitchCompat control
159159
- NOT a blocking overlay - user can interact with app regardless of state
160160
161-
4. LOGIN USER button:
161+
4. "Logged in as" display (ABOVE the buttons, only visible when logged in):
162+
- Prominent green CardView background (#E8F5E9)
163+
- "Logged in as:" label (16sp)
164+
- External User ID displayed large and centered (22sp bold, green #2E7D32)
165+
- Positioned ABOVE the Login/Switch User button
166+
167+
5. LOGIN USER button:
162168
- Shows "LOGIN USER" when no user is logged in
163169
- Shows "SWITCH USER" when a user is logged in
164170
- Opens dialog with empty "External User Id" field
165171
166-
5. External ID display (only visible when logged in):
167-
- Shows current external user ID below login button
168-
169172
6. LOGOUT USER button
170173
```
171174

@@ -274,12 +277,10 @@ SMS Section:
274277
Tags Section:
275278
- Section title: "Tags" with info icon for tooltip
276279
- RecyclerView showing key-value pairs
277-
- Each item shows: Key | Value with long-press to delete
280+
- Each item shows: Key | Value with X button to delete individually
278281
- "No Tags Added" text when empty
279282
- ADD TAG button → dialog with empty Key and Value fields
280-
- REMOVE ALL TAGS button:
281-
- Only visible when at least one tag exists
282-
- Red background color
283+
- NO "Remove All" button - tags are removed individually only
283284
```
284285

285286
### Prompt 2.10 - Outcome Events Section
@@ -299,9 +300,13 @@ Outcome Events Section:
299300
Triggers Section:
300301
- Section title: "Triggers" with info icon for tooltip
301302
- RecyclerView showing key-value pairs
302-
- Each item shows: Key | Value with long-press to delete
303+
- Each item shows: Key | Value with X button to delete individually
303304
- "No Triggers Added" text when empty
304305
- ADD TRIGGER button → dialog with empty Key and Value fields
306+
- CLEAR TRIGGERS button:
307+
- Only visible when at least 1 trigger exists
308+
- Red background color
309+
- Clears all triggers at once
305310
306311
IMPORTANT: Triggers are stored IN MEMORY ONLY during the app session.
307312
- triggersList is a mutableListOf<Pair<String, String>>() in MainViewModel
@@ -343,10 +348,13 @@ Loading indicator overlay:
343348
- Add ProgressBar overlay to activity_main.xml (covers entire screen with semi-transparent background)
344349
- Add isLoading LiveData to MainViewModel
345350
- Show/hide based on isLoading state
351+
- IMPORTANT: Add 100ms delay after populating data before dismissing loading indicator
352+
- This ensures UI (RecyclerViews, adapters) has time to render
353+
- Use kotlinx.coroutines.delay(100) after setting all LiveData values
346354
347355
On cold start:
348356
- Check if OneSignal.User.onesignalId is not null
349-
- If exists: show loading → call fetchUserDataFromApi() → populate UI → hide loading
357+
- If exists: show loading → call fetchUserDataFromApi() → populate UI → delay 100ms → hide loading
350358
- If null: just show empty state (no loading indicator)
351359
352360
On login (LOGIN USER / SWITCH USER):
@@ -355,7 +363,7 @@ On login (LOGIN USER / SWITCH USER):
355363
- Clear old user data (aliases, emails, sms, triggers)
356364
- Wait for onUserStateChange callback
357365
- onUserStateChange calls fetchUserDataFromApi()
358-
- fetchUserDataFromApi() populates UI and hides loading
366+
- fetchUserDataFromApi() populates UI, delays 100ms, then hides loading
359367
360368
On logout:
361369
- Show loading indicator
@@ -461,10 +469,21 @@ Create TooltipHelper.kt:
461469
462470
object TooltipHelper {
463471
private var tooltips: Map<String, TooltipData> = emptyMap()
472+
private var initialized = false
464473
465474
fun init(context: Context) {
466-
// Load tooltip_content.json from assets
467-
// Parse JSON into tooltips map
475+
if (initialized) return
476+
477+
// IMPORTANT: Load on background thread to avoid blocking app startup
478+
CoroutineScope(Dispatchers.IO).launch {
479+
// Load tooltip_content.json from assets
480+
// Parse JSON into tooltips map
481+
482+
withContext(Dispatchers.Main) {
483+
// Update tooltips map on main thread
484+
initialized = true
485+
}
486+
}
468487
}
469488
470489
fun getTooltip(key: String): TooltipData?
@@ -527,7 +546,12 @@ MainViewModel holds in memory:
527546
- Cleared on app restart
528547
- Used for testing IAM trigger conditions
529548
530-
- aliasesList, emailsList, smsNumbersList:
549+
- aliasesList:
550+
- Populated from REST API on each session start
551+
- When user adds alias locally, added to list immediately (SDK syncs async)
552+
- Fetched fresh via fetchUserDataFromApi() on login/app start
553+
554+
- emailsList, smsNumbersList:
531555
- Populated from REST API on each session
532556
- Not cached locally
533557
- Fetched fresh via fetchUserDataFromApi()
@@ -644,14 +668,41 @@ If you change the package name, you must also update these files with your own F
644668

645669
---
646670

671+
## Phase 7: Important Implementation Details
672+
673+
### Alias Management
674+
675+
```
676+
Aliases are managed with a hybrid approach:
677+
678+
1. On app start/login: Fetched from REST API via fetchUserDataFromApi()
679+
2. When user adds alias locally:
680+
- Call OneSignal.User.addAlias(label, id) - syncs to server async
681+
- Immediately add to local aliasesList (don't wait for API)
682+
- This ensures instant UI feedback while SDK syncs in background
683+
3. On next app launch: Fresh data from API includes the synced alias
684+
```
685+
686+
### Notification Permission
687+
688+
```
689+
Notification permission is automatically requested when MainActivity loads:
690+
- Call viewModel.promptPush() at end of onCreate()
691+
- This ensures prompt appears after user sees the app UI
692+
- PROMPT PUSH button remains as fallback if user initially denied
693+
- Button hidden once permission is granted
694+
```
695+
696+
---
697+
647698
## Summary
648699

649700
This app demonstrates all OneSignal Android SDK features:
650701
- User management (login/logout, aliases)
651-
- Push notifications (subscription, sending)
702+
- Push notifications (subscription, sending, auto-permission prompt)
652703
- Email and SMS subscriptions
653-
- Tags for segmentation
654-
- Triggers for in-app message targeting (in-memory only)
704+
- Tags for segmentation (individual remove only, no bulk remove)
705+
- Triggers for in-app message targeting (in-memory only, with Clear Triggers)
655706
- Outcomes for conversion tracking
656707
- Event tracking
657708
- In-app messages (display and testing)
@@ -664,3 +715,5 @@ The app is designed to be:
664715
3. **Clean** - MVVM architecture with centralized OneSignal code
665716
4. **Cross-platform ready** - Tooltip content in JSON for sharing across wrappers
666717
5. **Session-based triggers** - Triggers stored in memory only, cleared on restart
718+
6. **Responsive UI** - Loading indicator with delay to ensure UI populates before dismissing
719+
7. **Performant** - Tooltip JSON loaded on background thread

0 commit comments

Comments
 (0)