Cap-go / capacitor-updater

Capacitor plugin for Instant updates: Ship updates, fixes, changes, and features within minutes
https://capgo.app
Mozilla Public License 2.0
529 stars 106 forks source link

feat: I migrated the cordova version, and index.html will be lost after hot update. But when the app is opened again, index.html returns to normal. #442

Open waliu opened 2 months ago

waliu commented 2 months ago

Feature Request

Description

After many updates, occasionally when entering the plug-in, a prompt will appear that the version is built-in. Index.html will be lost. I guess the reason is that I didn't set setServerBasePath and setServerAssetPath, but cordova I don't know how to set

Open the APP again, and index.html magically appears again.

Platform(s)

cordova 13.0.0 Android

Preferred Solution

Can you help me deal with this error? How can I contact you? My Discord account : galen_90942 Thanks

waliu commented 2 months ago

lost index.html app image image

Restart app Normal display image

waliu commented 2 months ago

 public void initialize(CordovaInterface cordova, CordovaWebView webView) {
    this.counterActivityCreate++;
    this.prefs = this.cordova.getContext()
      .getSharedPreferences(WEBVIEW_PREFS_NAME, Activity.MODE_PRIVATE);
    this.editor = this.prefs.edit();

    try {
      this.implementation = new CapacitorUpdater() {
        @Override
        public void notifyDownload(final String id, final int percent) {
          HotUpdate.this.notifyDownload(id, percent);
        }

        @Override
        public void directUpdateFinish(final BundleInfo latest) {
          try {
            HotUpdate.this.directUpdateFinish(latest);
          } catch (JSONException e) {
            throw new RuntimeException(e);
          }
        }

        @Override
        public void notifyListeners(final String id, final JSONObject res) {
          HotUpdate.this.notifyListeners(id, res);
        }
      };
      final PackageInfo pInfo = this.cordova.getContext().getPackageManager().getPackageInfo(this.cordova.getContext().getPackageName(), 0);
      this.implementation.activity = this.cordova.getActivity();
// TODO I suspect the error is here 
      this.implementation.versionBuild = preferences.getString("version", pInfo.versionName);
      this.implementation.PLUGIN_VERSION = this.PLUGIN_VERSION;
      this.implementation.versionCode = Integer.toString(pInfo.versionCode);
      this.implementation.requestQueue = Volley.newRequestQueue(
        this.cordova.getContext()
      );
      final String signKeyStr = preferences.getString("signKey", "");
      if (signKeyStr.length() > 0) {
        this.implementation.signKey = CryptoCipher.stringToPublicKey(
          signKeyStr
        );
      }

      this.implementation.directUpdate = preferences.getBoolean("directUpdate", false);
      this.currentVersionNative = new Version(preferences.getString("version", pInfo.versionName));
    } catch (final PackageManager.NameNotFoundException e) {
      Log.e(CapacitorUpdater.TAG, "Error instantiating implementation", e);
      return;
    } catch (final Exception e) {
      Log.e(
        CapacitorUpdater.TAG,
        "Error getting current native app version",
        e
      );
      return;
    }

    this.implementation.appId = InternalUtils.getPackageName(
      this.cordova.getContext().getPackageManager(),
      this.cordova.getContext().getPackageName()
    );
    this.implementation.appId = preferences.getString("appId", this.implementation.appId);
    if (this.implementation.appId == null || this.implementation.appId.isEmpty()) {
      // crash the app
      throw new RuntimeException(
        "appId is missing in capacitor.config.json or plugin config, and cannot be retrieved from the native app, please add it globally or in the plugin config"
      );
    }
    Log.i(CapacitorUpdater.TAG, "appId: " + implementation.appId);
    this.implementation.privateKey = preferences.getString("privateKey", defaultPrivateKey);
    this.implementation.statsUrl = preferences.getString("statsUrl", statsUrlDefault);
    this.implementation.channelUrl = preferences.getString("channelUrl", channelUrlDefault);
    int userValue = preferences.getInteger("periodCheckDelay", 0);
    this.implementation.defaultChannel = preferences.getString("defaultChannel", "");
    if (userValue >= 0 && userValue <= 600) {
      this.periodCheckDelay = 600 * 1000;
    } else if (userValue > 600) {
      this.periodCheckDelay = userValue * 1000;
    }

    this.implementation.documentsDir = this.cordova.getContext().getFilesDir();
    this.implementation.prefs = this.prefs;
    this.implementation.editor = this.editor;
    this.implementation.versionOs = Build.VERSION.RELEASE;
    this.implementation.deviceID = this.prefs.getString(
      "appUUID",
      UUID.randomUUID().toString()
    );
    this.editor.putString("appUUID", this.implementation.deviceID);
    this.editor.commit();
    Log.i(
      CapacitorUpdater.TAG,
      "init for device " + this.implementation.deviceID
    );
    Log.i(
      CapacitorUpdater.TAG,
      "version native " + this.currentVersionNative.getOriginalString()
    );
    this.autoDeleteFailed = preferences
      .getBoolean("autoDeleteFailed", true);
    this.autoDeletePrevious = preferences
      .getBoolean("autoDeletePrevious", true);
    this.updateUrl = preferences.getString("updateUrl", updateUrlDefault);
    this.autoUpdate = preferences.getBoolean("autoUpdate", true);
    this.appReadyTimeout = preferences.getInteger("appReadyTimeout", 10000);
    this.implementation.timeout = preferences.getInteger("responseTimeout", 20) * 1000;
    boolean resetWhenUpdate = preferences.getBoolean("resetWhenUpdate", true);
    this.implementation.autoReset();
    if (resetWhenUpdate) {
      this.cleanupObsoleteVersions();
    }
    this.checkForUpdateAfterDelay();
  }

  private void semaphoreWait(Number waitTime) {
    Log.i(CapacitorUpdater.TAG, "semaphoreWait " + waitTime);
    try {
      //        Log.i(CapacitorUpdater.TAG, "semaphoreReady count " + CapacitorUpdaterPlugin.this.semaphoreReady.getCount());
      semaphoreReady.awaitAdvanceInterruptibly(
        semaphoreReady.getPhase(),
        waitTime.longValue(),
        TimeUnit.SECONDS
      );
      //        Log.i(CapacitorUpdater.TAG, "semaphoreReady await " + res);
      Log.i(
        CapacitorUpdater.TAG,
        "semaphoreReady count " + semaphoreReady.getPhase()
      );
    } catch (InterruptedException e) {
      Log.i(CapacitorUpdater.TAG, "semaphoreWait InterruptedException");
      e.printStackTrace();
    } catch (TimeoutException e) {
      throw new RuntimeException(e);
    }
  }

protected boolean _reload() {
    final String path = this.implementation.getCurrentBundlePath();
    this.semaphoreUp();
    Log.i(CapacitorUpdater.TAG, "Reloading: " + path);
    if (this.implementation.isUsingBuiltin()) {
// TODO I suspect the error is here 
//      this.bridge.setServerAssetPath(path);
    } else {
// TODO I suspect the error is here 
//      this.bridge.setServerBasePath(path);
    }
    this.checkAppReady();
    this.notifyListeners("appReloaded", new JSONObject());
    return true;
  }

I suspect the error is here but i can't solve it How to set up Cordoba Set server base path

riderx commented 2 months ago

Wait you mean you back ported the code in cordova ? I think it will be way easier for you to migrate to capacitor, we tried to make the plugin for cordova but that hard things do not work the same in cordova :/

waliu commented 2 months ago

Yes, our project cannot be quickly migrated to Capacitor because it has heavy historical baggage. So a cordova plugin is needed. I know capacitor development plugin is much simpler.

waliu commented 2 months ago

At present, we can only complete the cordova plug-in first, and then do the capacitor migration when time is enough.

waliu commented 2 months ago

In fact, hot updates have been implemented。Currently, index.html is missing in the builtin version. So I would like your help.

WcaleNieWolny commented 2 months ago

Let me confirm, you have been able to hot-reload but after you reopen the app the update doesn't persist?

What platform (IOS/Android) do you use?

WcaleNieWolny commented 2 months ago

Oh, I see the issue. Let me look for an IMPL

WcaleNieWolny commented 2 months ago

I would likely try to use this method

Although, the cordova-plugin-code-push is deprecated I would still give it a try. Other than this plugin I don't know where you could look for some code

waliu commented 2 months ago

@WcaleNieWolny It was because cordova-plugin-code-push was no longer maintained that I migrated from the capacitive updater to cordova. Although capacitors are now recommended, I had to get cordova running. I have solved the Cordoba Fever related issues.

waliu commented 2 months ago

@WcaleNieWolny
The plug-in is made according to capacitor-updater.

WcaleNieWolny commented 2 months ago

Would you mind sharing your solution for using capacitor updater with Cordova? How did you end up resolving the issue?

waliu commented 2 months ago

I will consider sharing it later

waliu commented 2 months ago

Currently I have only migrated the Android version

WcaleNieWolny commented 2 months ago

That is okay, your knowledge on this issue is still really useful.

waliu commented 2 months ago

Excuse me, after the capacitor-updater is hot updated, can it be restarted and loaded with index.html?

WcaleNieWolny commented 2 months ago

Yes, I recommend copying the IOS initialLoad logic into android

riderx commented 2 months ago

@waliu let's create a repo and @WcaleNieWolny can help you make it happen

riderx commented 1 month ago

@waliu where are you with this ? did you made it work?