new_version
new_version copied to clipboard
Play store changes => StateError: Bad state: No element
Google Play store looks very different since yesterday or today?
I've got some error messages popping up now.
StateError: Bad state: No element
File "list.dart", line 167, in ListMixin.firstWhere
File "new_version.dart", line 157, in NewVersion._getAndroidStoreVersion
File "<asynchronous suspension>"
File "new_version.dart", line 94, in NewVersion.showAlertIfNecessary
So I think changes are necessary. You can find the version of the app in a modal @ "About this app ->"
Yes looks like it, thanks for reporting. This will probably break the plugin until I determine the new HTML elements.
Looks like they are rolling it out gradually? Right now I see the old play store in my browser again.
When is the next update for this package? My users are facing stuck issue because of this error.
Hi, any updates regarding this issue? Didn't even know about the store change since said breaking changes haven't reflected in my area till like yesterday/today
When can I get another update for this package?
Dear author let us know whether this issue is going to fix or not. If not then we will drop this package or let us know the estimation time to fix. thousands of devices are stuck in launcher screen due to this error.
Dear author let us know whether this issue is going to fix or not. If not then we will drop this package or let us know the estimation time to fix. thousands of devices are stuck in launcher screen due to this error.
Agreed. I am waiting the fix too. Please let us know ASAP when you fixed.
My client thought I'm the one who cause the issue. I've removed the plugin and upload to AppStore & PlayStore. If the problem fix I I will use It back.
I can confirm I'm experiencing the same problem here as everyone.
Same here. Dear Author please do let us know ASAP about this fix. Is there an alternative to this package if this won't be fixed anytime soon?
same issue i faced now. please find the solution by author. plz client is waiting this Error is :
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Bad state: No element
E/flutter ( 8554): #0 ListMixin.firstWhere (dart:collection/list.dart:167:5)
E/flutter ( 8554): #1 NewVersion._getAndroidStoreVersion (package:new_version/new_version.dart:153:51)
E/flutter ( 8554):
@timtraversy So apparently the store changed for more users. Any idea how to proceed?
I looked a bit into it myself, but getting the version from the HTML page itself seems more difficult because it doesn't appear in the source code on a page load anymore. It's all javascript-driven it seems.
Also: what if they decide to change a class name anytime soon again? Is there is more robust option to get the latest version of an app?
@peterhijma From now on, remote configuration needs to be added. But when app is uploaded to Android, you have to do it in Firebase. so this is not proper solution. please find what class is used by javascript? so this is easily to find this. whats version is used in latest playstore.
final additionalInfoElements = document.getElementsByClassName('hAyfc');
This class is not found. beacuse google has changed design of play store.
Hi. is there going to be a fix for this anytime soon?
Unfortunately, there is not an easy fix for this. The new Play Store listing design does not include the app version number. For example: https://play.google.com/store/apps/details?id=com.google.android.apps.cloudconsole
There may be some other site where the version is listed, but someone will have to find it.
actually the designer has changed a little I can't find the app version
In section „about this app“ is the version. Does this help?
Good catch. That's closer, but that HTML element is only shown after a Javascript function is triggered, so we wouldn't be able to scrape it with a simple HTTP request as we do now.
It looks like the version info is pre-fetched though, and hidden in a huge block of in-line JS. So there might be a way to scrape out of there. But who knows if the format they return it in will be consistent.
https://pub.dev/packages/webdriver is a possibility.
Right now, I'm leaning towards turning off Android support and releasing a version without it. But I'll give it another day to see if anything comes up.
If anyone is up for a challenge:
- Go to random app with no reviews - https://play.google.com/store/apps/details?id=com.aakenya.testapp
- Look at page source - view-source:https://play.google.com/store/apps/details?id=com.aakenya.testapp
- CTRL-F for the version number - currently 1.0.14
- See if there's any possible way to extract that value from that blob of js/json
That's probably the only way.
JavaScript Code
import { JSOM } from 'jsdom';
import axios from 'axios';
const res = await axios('https://play.google.com/store/apps/details?id=com.yourapp');
const dom = new JSDOM(res.data);
const scripts = Array.from(dom.window.document.querySelectorAll('script'));
const script = scripts.find(s => s.textContent && s.textContent.includes('/store/apps/developer'));
const matches = script.textContent.match(versionStringRegex);
const match = matches[0];
const version = match.replace(/"/g, '');
console.log(version); // '1.2.345'
@timtraversy can u check it out ?..
Java code
class AppVersionParser {
suspend fun versionForIdentifier(bundleID: String): String? {
val userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_3_1) AppleWebKit/605.1.15 (KHTML, like Gecko) " +
"Version/15.3 Safari/605.1.15"
val document: Document
try {
document = Jsoup.connect("https://play.google.com/store/apps/details?id=$bundleID&hl=en")
.timeout(5000)
.userAgent(userAgent)
.referrer("https://www.google.com")
.get()
} catch (e: Exception) {
logger.error("Failed to get Google Play info for $bundleID\n\t${e.toStandardString()}")
return null
}
return parseDocument(document)
}
fun parseDocument(document: Document): String? {
val HTML = document.toString()
val policyMarker = "" // INSERT YOUR PRIVACY POLICY URL
val policyUrlIndex = HTML.lastIndexOf(policyMarker)
val versionStart = HTML.indexOf("\"", startIndex = policyUrlIndex + policyMarker.length + 1) + 1 // "
val versionEnd = HTML.indexOf("\"", startIndex = versionStart + 1)
return HTML.substring(startIndex = versionStart, endIndex = versionEnd)
}
}`
For me, some changes in _getAndroidStoreVersion worked.
Future<VersionStatus?> _getAndroidStoreVersion(
PackageInfo packageInfo) async {
final id = androidId ?? packageInfo.packageName;
final uri =
Uri.https("play.google.com", "/store/apps/details", {"id": "$id"});
final response = await http.get(uri);
if (response.statusCode != 200) {
debugPrint('Can\'t find an app in the Play Store with the id: $id');
return null;
}
final document = parse(response.body);
String storeVersion = '0.0.0';
String? releaseNotes;
final additionalInfoElements = document.getElementsByClassName('hAyfc');
if (additionalInfoElements.isNotEmpty) {
final versionElement = additionalInfoElements.firstWhere(
(elm) => elm.querySelector('.BgcNfc')!.text == 'Current Version',
);
storeVersion = versionElement.querySelector('.htlgb')!.text;
final sectionElements = document.getElementsByClassName('W4P4ne');
final releaseNotesElement = sectionElements.firstWhereOrNull(
(elm) => elm.querySelector('.wSaTQd')!.text == 'What\'s New',
);
releaseNotes = releaseNotesElement
?.querySelector('.PHBdkd')
?.querySelector('.DWPxHb')
?.text;
} else {
final scriptElements = document.getElementsByTagName('script');
final infoScriptElement = scriptElements.firstWhere(
(elm) => elm.text.contains('key: \'ds:4\''),
);
final param = infoScriptElement.text.substring(20, infoScriptElement.text.length - 2)
.replaceAll('key:', '"key":')
.replaceAll('hash:', '"hash":')
.replaceAll('data:', '"data":')
.replaceAll('sideChannel:', '"sideChannel":')
.replaceAll('\'', '"')
.replaceAll('owners\"', 'owners');
final parsed = json.decode(param);
final data = parsed['data'];
storeVersion = data[1][2][140][0][0][0];
releaseNotes = data[1][2][144][1][1];
}
return VersionStatus._(
localVersion: _getCleanVersion(packageInfo.version),
storeVersion: _getCleanVersion(forceAppVersion ?? storeVersion),
appStoreLink: uri.toString(),
releaseNotes: releaseNotes,
);
}
Still not sure if play store HTML will be consistent or not but it worked for now.
I'm getting the same error
is there any solution because user can't visit to my application it stuck on the splash screen
and my application is live
I'm getting the same error is there any solution because user can't visit to my application it stuck on the splash screen and my application is live
same here
To those this is breaking: you will have to release a new version of your apps to fix this issue. I would recommend just doing that now, and removing the calls to this plugin. This was an unforseen change in the Play Console, we're working on a fix.
Nice concepts above, thank you!
@prakasharyaman - This is a clever idea, but people format there versions different ways. Also, the HTML contains multiple version strings from past versions, so we would have to add some logic to fix that as well.
@ankitpanwar8979 - This is my preferred solution. The nested array doesn't seem like it will remain stable as the Play site changes, but best we can do for now.
3 days ago •
can u explain code _getCleanVersion is what for?
Try This
Works for now
public function getAndroidVersion(string $storeUrl): string
{
$html = file_get_contents($storeUrl);
$matches = [];
preg_match('/\[\[\[\"\d+\.\d+\.\d+/', $html, $matches);
if (empty($matches) || count($matches) > 1) {
throw new Exception('Could not fetch Android app version info!');
}
return substr(current($matches), 4);
}
@timtraversy same issue is facing ( Bad state: No element ) Now what is the solution for it.
Google Play store looks very different since yesterday or today?
I've got some error messages popping up now.
StateError: Bad state: No element File "list.dart", line 167, in ListMixin.firstWhere File "new_version.dart", line 157, in NewVersion._getAndroidStoreVersion File "<asynchronous suspension>" File "new_version.dart", line 94, in NewVersion.showAlertIfNecessary
So I think changes are necessary. You can find the version of the app in a modal @ "About this app ->"
Please provide me solution ASAP in "Bad state: No element"