Skip to content

Behavior question: RewardedAdGate grants the reward even when the ad fails to load / is blocked #242

Description

@evan188199-tech

Potential bug / behavior question

RewardedAdGate grants the reward (starts the workout) even when the rewarded ad fails to load or is never shown. An ad-blocking user can always bypass the gate.

Where

src/components/ads/custom/RewardedAdGate.tsx:

const handleWatchAd = useCallback(() => {
  if (!window.ezRewardedAds?.ready) {
    setOpen(false);
    onRewardGranted();          // (1) SDK not ready → reward granted
    return;
  }
  setLoading(true);
  window.ezRewardedAds.requestAndShow((result) => {
    setLoading(false);
    setOpen(false);
    if (result.reward || !result.status) {   // (2) ad failed (!status) → reward granted
      onRewardGranted();
    }
  });
}, [onRewardGranted]);

onRewardGranted is wired to onStartWorkout (workout-stepper-footer.tsx:49), so the gate controls whether a non-premium user can start the workout.

Impact

Two paths grant the reward without a completed ad:

  1. SDK not ready (!window.ezRewardedAds?.ready) — e.g. the Ezoic script is blocked by an ad blocker, failed to load, or hasn't initialized. The user clicks "watch ad", the SDK isn't there, and the workout starts anyway.
  2. Ad callback reports failure (!result.status) — if the ad request errors out, the reward is granted.

Combined with premium users skipping the gate entirely (line 33), the net effect is that the rewarded-ad gate is advisory: anyone using an ad blocker always passes it for free, which defeats the monetization intent.

Question for maintainers

This may be intentional "fail-open" UX (never block a user from working out because of an ad-system failure). If so, feel free to close. If the intent is to actually gate the workout behind a completed ad, the fix is to grant the reward only on a real completion and show a fallback (e.g. "ad unavailable, try again / start anyway with a clear notice") rather than silently succeeding.

I can open a PR for either direction — wanted to confirm intent first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions