I am trying to implement in app update in my unity game.
For testing, I just implement flexible update and create new release in internal testing track and upload one more version with higher version code.
When I test it, the flexible update prompt is showing correctly, but when click on update, it is throwing ErrorUserCancelled.
Here is my in app update manager. I have written code after reading Google doc, but there are lot of things unclear, so I used chat gpt but still something is wrong.
Here is error I get in logcat:

My code:
using System.Collections;
using UnityEngine;
using Google.Play.AppUpdate;
using Google.Play.Common;
using UnityEngine.UI;
public class InAppUpdate : MonoBehaviour
{
private AppUpdateManager appUpdateManager;
// The result from checking for an update, contains information about available updates.
private AppUpdateInfo appUpdateInfoResult;
void Start()
{
// Initialize the AppUpdateManager.
appUpdateManager = new AppUpdateManager();
// Start checking for updates immediately.
StartCoroutine(CheckForUpdate());
}
IEnumerator CheckForUpdate()
{
// Creates a PlayAsyncOperation to check for update info.
PlayAsyncOperation<AppUpdateInfo, AppUpdateErrorCode> appUpdateInfoOperation =
appUpdateManager.GetAppUpdateInfo();
// Wait until the operation is done.
yield return appUpdateInfoOperation;
// If the operation encounters an error, log it and return.
if (appUpdateInfoOperation.Error != AppUpdateErrorCode.NoError)
{
Debug.LogError("Error checking for update: " + appUpdateInfoOperation.Error);
yield break;
}
// Get the AppUpdateInfo result.
appUpdateInfoResult = appUpdateInfoOperation.GetResult();
// Check if an update is available and if a flexible update is allowed.
if (appUpdateInfoResult.UpdateAvailability == UpdateAvailability.UpdateAvailable)
{
if (appUpdateInfoResult.IsUpdateTypeAllowed(AppUpdateOptions.ImmediateAppUpdateOptions()))
{
StartCoroutine(StartFlexibleUpdate());
}
}
else
{
Debug.LogError("Update is not available");
}
}
IEnumerator StartFlexibleUpdate()
{
// Define app update options for a flexible update.
var appUpdateOptions = AppUpdateOptions.FlexibleAppUpdateOptions();
// Creates an AppUpdateRequest to monitor the update flow.
var startUpdateRequest = appUpdateManager.StartUpdate(appUpdateInfoResult, appUpdateOptions);
// Loop while the update is not yet done.
while (!startUpdateRequest.IsDone)
{
// For flexible flow, the user can continue to use the app while
// the update downloads in the background.
// No UI elements here, as requested.
yield return null;
}
// Once IsDone, check for errors from the StartUpdate operation.
if (startUpdateRequest.Error != AppUpdateErrorCode.NoError)
{
Debug.LogError("Error starting flexible update: " + startUpdateRequest.Error);
yield break;
}
// After the StartUpdate operation is done, re-fetch AppUpdateInfo to get the latest InstallStatus.
var updatedAppUpdateInfoOperation = appUpdateManager.GetAppUpdateInfo();
yield return updatedAppUpdateInfoOperation;
if (updatedAppUpdateInfoOperation.Error != AppUpdateErrorCode.NoError)
{
Debug.LogError("Error re-fetching update info after download: " + updatedAppUpdateInfoOperation.Error);
yield break;
}
AppUpdateInfo updatedAppUpdateInfo = updatedAppUpdateInfoOperation.GetResult();
// Check if the download completed successfully using the updated InstallStatus.
if (updatedAppUpdateInfo.AppUpdateStatus == AppUpdateStatus.Downloaded)
{
// Downloaded successfully, proceed to complete the update.
StartCoroutine(CompleteFlexibleUpdate());
}
else
{
// Handle other download statuses if necessary (e.g., pending, failed).
// This might occur if the download didn't complete for some reason even after IsDone.
Debug.LogWarning("Flexible update install status after download: " + updatedAppUpdateInfo.AppUpdateStatus);
}
}
IEnumerator CompleteFlexibleUpdate()
{
// Request the app update to be installed.
var result = appUpdateManager.CompleteUpdate();
yield return result;
// This line should typically not be reached if the update is successful,
// as the app will restart. If it is reached, an error occurred.
if (result.Error != AppUpdateErrorCode.NoError)
{
Debug.LogError("Error completing flexible update: " + result.Error);
}
}
}
I follow all things uploading on testing tracks and increment version code. My device is already in testing emails.
I downloaded older version from internal testing link and then I upload new version.
I am getting prompt correctly, but update button not start updating instead throwing error user cancelled, something is wrong in my implementation maybe.
The thing is I uploaded 20+ version again in testing tracks because I get a "class missing" error, but somehow fixed it by adding in main template.
At this time, I am very frustrated by uploading new versions again and again.
AppUpdateManageris built-in from Google .. the value ofstartUpdateRequest.Erroras per the posted log isErrorUserCanceled