Skyost / RateMyApp

This plugin allows to kindly ask users to rate your app if custom conditions are met (eg. install time, number of launches, etc...).

Home Page:https://pub.dev/packages/rate_my_app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dialog only pops up on iOS.

FisherWL opened this issue · comments

Describe the bug
Dialog doesn't open on emulator or physical android phone.

To Reproduce

import 'package:flutter/material.dart';
import 'package:rate_my_app/rate_my_app.dart';

RateMyApp rateMyApp = RateMyApp(
  preferencesPrefix: 'rateMyApp_',
  minDays: 0,
  minLaunches: 0,
  remindDays: 0,
  remindLaunches: 0,
  appStoreIdentifier: '100000000',
  googlePlayIdentifier: 'com.example.rateMyApp',
);

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  rateMyApp.init().then((_) {
    runApp(TestApp());
  });
}

class TestApp extends StatefulWidget {
  @override
  _TestAppState createState() => _TestAppState();
}

class _TestAppState extends State<TestApp> {
  @override
  void initState() {
    rateMyApp.init().then((_) {
      if (rateMyApp.shouldOpenDialog) {
        rateMyApp.showRateDialog(
          context,
          title: 'Rate this app',
          message: 'Please rate',
          rateButton: 'RATE',
          noButton: 'NO THANKS',
          laterButton: 'MAYBE LATER',
        );
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Center(child: Text('test')),
      ),
    );
  }
}

Expected behavior
Dialog should open on emulator and physical android phone.

Additional context
I guess it's related to the "Where to initialize Rate My App" section,
I don't fully understand "initialize Rate my app in your main() method".
RateMyAppBuilder() works well to let the dialog show up,
but it's not compatible with it's children layout (namely admob banner ads at bottom and keyboard, but that's a different question).

Your initialization code is fine. Keep in mind that super.initState(); should be the first line of your overrided initState() method.

By the way, you're initializing the same instance twice. This is not required, and in fact, not recommended at all. Try something like this and tell me if it works :

import 'package:flutter/material.dart';
import 'package:rate_my_app/rate_my_app.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(TestApp());
}

class TestApp extends StatefulWidget {
  @override
  _TestAppState createState() => _TestAppState();
}

class _TestAppState extends State<TestApp> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async { // You need to wait a frame if you want to use your BuildContext here.
      RateMyApp rateMyApp = RateMyApp(
        preferencesPrefix: 'rateMyApp_', // Not required.
        minDays: 0,
        minLaunches: 0,
        remindDays: 0,
        remindLaunches: 0,
        appStoreIdentifier: '100000000', // Only required if you're targeting an iOS version before iOS 10.3.
        googlePlayIdentifier: 'com.example.rateMyApp', // Not required as it will automatically find your package name in your AndroidManifest.xml.
      );
      await rateMyApp.init();
      if (rateMyApp.shouldOpenDialog) {
        rateMyApp.showRateDialog(
          context,
          title: 'Rate this app',
          message: 'Please rate',
          rateButton: 'RATE', // Not required.
          noButton: 'NO THANKS', // Not required.
          laterButton: 'MAYBE LATER', // Not required.
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: Center(child: Text('test')),
      ),
    );
  }
}

See @required annotations to see what is required.

Thank you @Skyost
I got No MaterialLocalizations found. running the sample code above,
I move MaterialApp() up then it seems working:

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TestApp(),
    );
  }
}