Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to force update and not to let user to use app? #17

Open
NTMS2017 opened this issue Jan 14, 2020 · 16 comments
Open

How to force update and not to let user to use app? #17

NTMS2017 opened this issue Jan 14, 2020 · 16 comments

Comments

@NTMS2017
Copy link

NTMS2017 commented Jan 14, 2020

Hi,

I need to force user to update app always. If they not going to update I should block user not to use app. Also I created a example app and try to use your example, but it didn't work and I guess there was no app that I am running in Google Play.

Later I update my app package name which is already in app store and I keep getting error as shown below.

I/flutter ( 7751): PlatformException(Failed to bind to the service., null, null)

Last, your example uses a button to check for update how to use this without button but in initState? Thanks

Note: I all need is to check for Update initial app initialization than force to make performImmediateUpdate().

My original app:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setEnabledSystemUIOverlays([]);
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);

    return new MaterialApp(
      // TODO: SUPPORTED LOCALE
      localizationsDelegates: [
        const LangDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        const FallbackCupertinoLocalisationsDelegate(),
      ],
      supportedLocales: [
        const Locale('tr', 'TR'),
        const Locale('en', 'US'),
        const Locale('ru', 'RU'),
      ],

      debugShowCheckedModeBanner: false,
      title: 'My Cep',
      theme: new ThemeData(
        primaryColor: capitalDarkGreen,
        fontFamily: "Roboto",
      ),
      home: new MyMainHomePage(),
    );
  }
}

And in MyMainHomePage I have PackageInfo and Connectivity in initState. So where I code the android app update?

Here is the full code (I am not sure where I am making mistake):

import 'package:flutter/material.dart';
import 'package:upgrader/upgrader.dart';
import 'dart:io' show Platform;
import 'dart:async';
import 'package:in_app_update/in_app_update.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  AppUpdateInfo _updateInfo;
  GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();
  bool _flexibleUpdateAvailable = false;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    checkForUpdate();
    //InAppUpdate.performImmediateUpdate().catchError((e) => _showError(e));
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> checkForUpdate() async {
    InAppUpdate.checkForUpdate().then((info) {
      setState(() {
        _updateInfo = info;
      });
    }).catchError((e) => _showError(e));
  }

  void _showError(dynamic exception) {
    _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text(exception.toString())));
    print(exception.toString());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('In App Update Example App'),
        ),
        body: _updateInfo?.updateAvailable == false
            ? new CircularProgressIndicator()
            : Platform.isAndroid == true
                ? Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      children: <Widget>[
                        Center(
                          child: Text('Update info: $_updateInfo'),
                        ),
                        RaisedButton(
                          child: Text('Check for Update'),
                          onPressed: () => checkForUpdate(),
                        ),
                        RaisedButton(
                          child: Text('Perform immediate update'),
                          onPressed: _updateInfo?.updateAvailable == true
                              ? () {
                                  InAppUpdate.performImmediateUpdate().catchError((e) => _showError(e));
                                }
                              : null,
                        ),
                        RaisedButton(
                          child: Text('Start flexible update'),
                          onPressed: _updateInfo?.updateAvailable == true
                              ? () {
                                  InAppUpdate.startFlexibleUpdate().then((_) {
                                    setState(() {
                                      _flexibleUpdateAvailable = true;
                                    });
                                  }).catchError((e) => _showError(e));
                                }
                              : null,
                        ),
                        RaisedButton(
                          child: Text('Complete flexible update'),
                          onPressed: !_flexibleUpdateAvailable
                              ? null
                              : () {
                                  InAppUpdate.completeFlexibleUpdate().then((_) {
                                    _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text('Success!')));
                                  }).catchError((e) => _showError(e));
                                },
                        )
                      ],
                    ),
                  )
                : UpgradeAlert(
                    child: Center(child: Text('Checking...')),
                  ));
  }
}

@NTMS2017
Copy link
Author

After few days of searching it doesn't work on emulator. I install on my android phone and it worked. But I can see only availableVersionCode as 30. But my actual version is version: 2.3.4+34 on Google Play store. I try to make Perform immediate update and I can see the update page which has x on right hand corner which is close button. I press there to close it before update. And second time I try to run it I am keep getting MissingPluginExeption.

My question is how to force user to update and not to cancel it? Thanks

@NTMS2017
Copy link
Author

In Google Play Store my App Release: 2.3.4 and version code: 34

I open my project and change the version to: 2.3.3+33

When I run the app I got error that shown below. Any idea why I am getting this error

error info: InAppUpdateState{updateAvailable: false, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: null}

@jonasbark
Copy link
Owner

Please read https://developer.android.com/guide/playcore/in-app-updates#troubleshoot carefully. I'm pretty sure it won't work with your debug certificates in debug mode.

@NTMS2017
Copy link
Author

What do you mean in debug mode? I install app from Android Studio to my phone.

@NTMS2017
Copy link
Author

ok, it means:

Make sure that the app that you are testing in-app updates with has the same application ID and is signed with the same signing key as the one available from Google Play.

So I need to update my app with this plugin. Than later (1 day later in example) I have to update my again with new version code on Google play than I can test. ???

Problem is that If I use version as 1.2.0+5 it goes and finds the new update. but if I change version code lower than but closer to currently that available in App Store it doesn't update.

@NTMS2017
Copy link
Author

NTMS2017 commented Jan 17, 2020

I reduce my app versions to version: 1.2.4+10 and Now I got this:

info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}

also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false
what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?

@rahuldange09
Copy link

I reduce my app versions to version: 1.2.4+10 and Now I got this:

info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}

also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false
what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?

Same issue with me..... It's issue on google side not this plugin. If you clear play store cache and open play store and go to my apps and then open app it will show update.

@azhar1038
Copy link

I reduce my app versions to version: 1.2.4+10 and Now I got this:

info: InAppUpdateState{updateAvailable: true, immediateUpdateAllowed: false, flexibleUpdateAllowed: false, availableVersionCode: 30}

also it shows updateAvailable: true but both immediateUpdateAllowed and flexibleUpdateAllowed shows as a false
what do you mean availableVersionCode: 30? My app version code: 34 in Google Play. Next update should I have to incease the version code to 30 to 40 and than 50, 60 so on?

I am also seeing this. Though this happens only when I open app after clearing cache on play store. When I close the app and open again, it shows true for both update type.

@rubenvereecken
Copy link

To add to @mdazharuddin1011999, forcing an update check in the play store worked for me, even if I was just on internal testing. For that I followed the steps listed in the explanation of how to do alpha track in-app updates (even though I was on internal): https://stackoverflow.com/questions/56087064/how-can-i-test-in-app-updates-in-android

@azhar1038
Copy link

Yeah it works. If you are seeing "update available" for your app in My apps and games section of Play store, this package works like charm, doesn't matter if you are in internal or beta or production!

@fehernyul
Copy link

And that is exactly my problem. I have to go to PlayStore, I have to find "My apps and games" and I have to check upgrades BEFORE this plugin will find the upgraded version, which is actually already exists on the PlayStore.
Need that feature, which make this concept meaningless and check for upgrade directly in the Play Store and not in the device's PlayStore app's chache/memory/stored-datas, ...

@jonasbark
Copy link
Owner

@fehernyul Nonsense. The play store update list is cached and auto updates itself - something that nobody has control of. So you'll just have to wait until the update information arrives to this plugin as well.

@zjamshidi
Copy link

Did you find a solution to force the app update? I mean users could not use the app unless they update to the latest version.

@rubenvereecken
Copy link

@zjamshidi I store a "latest version" online somewhere (actually I use Firebase Remote Config but you could store it on your own server). On startup it fetches the version and if it's breaking with respect to the app's current version (Semver semantics), then the app routes to a captive screen.

If you're worried about your app not being able to start up without a connection because it would hang on fetching the version, just fetch the version when you do have a connection during the lifetime of the app.

@zjamshidi
Copy link

I do the the same for the "Latest Version". I was wondering if the library provides any solution for forcing users. I ended up calling "performUpdate" method in a loop :/

@rubenvereecken
Copy link

Aren't "immediate" updates forced anyway? For flexible ones you'd have to loop though yeah if the user does say no, but that probably defeats the point. https://developer.android.com/guide/playcore/in-app-updates

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants