google / google/play-in-app-updates-unity

ErrorUserCanceled on flexible update

Open
#3 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
3
Forks
8
PR merge metrics
No merged PRs in 30d

Description

I'm getting the flexible update popup and after I click update I'm always getting ErrorUserCanceled. After restarting the app the update is resumed, but i cannot display any download progress as i get cancel error. I'm testing my app on Internal testing track in GP. I'm installing a version from internal testing track and then uploading a new version to test the update.

Here's my code:
`
using System.Collections;
using Google.Play.AppUpdate;
using Google.Play.Common;
using UnityEngine;

public class UpdateManager : MonoBehaviour
{
private AppUpdateManager _appUpdateManager;
private AppUpdateRequest _updateRequest;
public ProgressBar progressBar;

private bool _checking;

void Start()
{
_appUpdateManager = new AppUpdateManager();
StartCoroutine(CheckForUpdateOnce());
}

void OnApplicationPause(bool pause)
{
if (!pause) StartCoroutine(CheckForUpdateOnce()); // resume handling
}

IEnumerator CheckForUpdateOnce()
{
Debug.Log("[Update] CheckForUpdateOnce start");

if (_appUpdateManager == null)
{
Debug.LogWarning("[Update] AppUpdateManager was null, creating a new one.");
_appUpdateManager = new AppUpdateManager();
}

if (_checking)
{
Debug.LogWarning("[Update] Already checking for update");
yield break;
}
_checking = true;

var infoOp = _appUpdateManager.GetAppUpdateInfo();
yield return infoOp;

if (infoOp == null)
{
Debug.LogError("[Update] infoOp is null");
yield break;
}

if (!infoOp.IsSuccessful)
{
Debug.LogWarning($"[Update] GetAppUpdateInfo failed: {infoOp.Error}");
_checking = false;
yield break;
}

var info = infoOp.GetResult();
if (info == null)
{
Debug.LogError("[Update] GetResult() returned null");
yield break;
}

Debug.Log($"[Update] info status: {info.AppUpdateStatus}, availability: {info.UpdateAvailability}, priority: {info.UpdatePriority}");

// Handle “update already in progress” (Immediate) on resume.
var immediateUpdateOptions = AppUpdateOptions.ImmediateAppUpdateOptions();
var flexibleUpdateOptions = AppUpdateOptions.FlexibleAppUpdateOptions();
if (info.UpdateAvailability == UpdateAvailability.DeveloperTriggeredUpdateInProgress &&
info.IsUpdateTypeAllowed(immediateUpdateOptions))
{
Debug.Log("[Update] Resume update");
var resumeReq = _appUpdateManager.StartUpdate(info, AppUpdateOptions.ImmediateAppUpdateOptions());
yield return resumeReq;
_checking = false;
yield break;
}

if (info.UpdateAvailability != UpdateAvailability.UpdateAvailable)
{
Debug.LogWarning("[Update] Update not available");
_checking = false;
yield break; // nothing to do
}

// Choose flow by priority (example policy).
var useImmediate = info.UpdatePriority >= 4 && info.IsUpdateTypeAllowed(immediateUpdateOptions);
var useFlexible = !useImmediate && info.IsUpdateTypeAllowed(flexibleUpdateOptions);

Debug.Log($"[Update] useImmediate: {useImmediate}, useFlexible: {useFlexible}");
if (!useImmediate && !useFlexible)
{
Debug.LogWarning("[Update] No allowed update types");
_checking = false;
yield break; // no allowed update types
}

var options = useImmediate
? AppUpdateOptions.ImmediateAppUpdateOptions()
: AppUpdateOptions.FlexibleAppUpdateOptions();

_updateRequest = _appUpdateManager.StartUpdate(info, options);
Debug.Log($"[Update] Error: {_updateRequest.Error}, isDone: {_updateRequest.IsDone}, Status: {_updateRequest.Status}, keepWaiting: {_updateRequest.keepWaiting}");

if (_updateRequest == null)
{
Debug.LogError("[Update] StartUpdate returned null");
yield break;
}

if (useFlexible && progressBar != null)
progressBar.gameObject.SetActive(true);

Debug.Log($"[Update] Starting to update");
// Poll status
while (!_updateRequest.IsDone)
{
if (useFlexible && progressBar != null)
{
// AppUpdateRequest.DownloadProgress is 0..1
progressBar.SetProgress(_updateRequest.DownloadProgress);
}
yield return null;
}

Debug.Log($"[Update] Finished downloading");

if (_updateRequest.Error != AppUpdateErrorCode.NoError)
{
Debug.LogWarning($"[Update] Update failed: {_updateRequest.Error}");
if (progressBar != null) progressBar.gameObject.SetActive(false);
_updateRequest = null;
_checking = false;
yield break;
}

if (useFlexible)
{
Debug.Log($"[Update] Complete flexible update");
// Normally prompt the user before restart; here we proceed directly.
var completeOp = _appUpdateManager.CompleteUpdate();
yield return completeOp;

if (!completeOp.IsSuccessful)
Debug.LogWarning($"[Update] CompleteUpdate failed: {completeOp.Error}");
// Successful complete will restart the app before this line.
}

if (progressBar != null) progressBar.gameObject.SetActive(false);
_updateRequest = null;
_checking = false;
}
}
`

Here's the log of exactly what is happening:
09-07 14:22:33.147 18257 18660 I Unity : [Update] CheckForUpdateOnce start
09-07 14:22:33.147 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:22:33.147 18257 18660 I Unity : d__6:MoveNext()
09-07 14:22:33.147 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:22:33.155 18257 18660 I Unity :
09-07 14:22:33.226 18257 18660 I Unity : [Update] info status: Unknown, availability: UpdateAvailable, priority: 0
09-07 14:22:33.226 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:22:33.226 18257 18660 I Unity : d__6:MoveNext()
09-07 14:22:33.226 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:22:33.226 18257 18660 I Unity :
09-07 14:22:33.227 18257 18660 I Unity : [Update] useImmediate: False, useFlexible: True
09-07 14:22:33.227 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:22:33.227 18257 18660 I Unity : d__6:MoveNext()
09-07 14:22:33.227 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:22:33.227 18257 18660 I Unity :
09-07 14:22:33.248 18257 18660 I Unity : [Update] Error: NoError, isDone: False, Status: Unknown, keepWaiting: True
09-07 14:22:33.248 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:22:33.248 18257 18660 I Unity : d__6:MoveNext()
09-07 14:22:33.248 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:22:33.248 18257 18660 I Unity :
09-07 14:22:33.249 18257 18660 I Unity : [Update] Starting to update
09-07 14:22:33.249 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:22:33.249 18257 18660 I Unity : d__6:MoveNext()
09-07 14:22:33.249 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:22:33.249 18257 18660 I Unity :
09-07 14:23:25.475 18257 18660 I Unity : [Update] CheckForUpdateOnce start
09-07 14:23:25.475 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:23:25.475 18257 18660 I Unity : d__6:MoveNext()
09-07 14:23:25.475 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:23:25.475 18257 18660 I Unity :
09-07 14:23:25.475 18257 18660 W Unity : [Update] Already checking for update
09-07 14:23:25.475 18257 18660 W Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:23:25.475 18257 18660 W Unity : d__6:MoveNext()
09-07 14:23:25.475 18257 18660 W Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:23:25.475 18257 18660 W Unity :
09-07 14:23:25.602 18257 18660 I Unity : [Update] Finished downloading
09-07 14:23:25.602 18257 18660 I Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:23:25.602 18257 18660 I Unity : d__6:MoveNext()
09-07 14:23:25.602 18257 18660 I Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
09-07 14:23:25.602 18257 18660 I Unity :
09-07 14:23:25.602 18257 18660 W Unity : [Update] Update failed: ErrorUserCanceled
09-07 14:23:25.602 18257 18660 W Unity : UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
09-07 14:23:25.602 18257 18660 W Unity : d__6:MoveNext()
09-07 14:23:25.602 18257 18660 W Unity : UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

Contributor guide

Open the contributing guide

Research direction

Start with AppUpdateManager.StartUpdate, AppUpdateRequest, and the OnApplicationPause resume path shown in the issue. Reproduce the flexible update on the Google Play Internal testing track and trace the request until it completes. Done means identifying why the request reports ErrorUserCanceled and restoring usable download progress or documenting the confirmed limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, unity
Domain
mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.