microsoft / appcenter-sdk-dotnet

Development repository for the App Center SDK for .NET platforms, including Xamarin
Other
308 stars 141 forks source link

Distribute on IOS randomly ask to reinstall the app #597

Closed sandorfr closed 5 years ago

sandorfr commented 6 years ago

In-App Updates are very unstable on IOS. It randomly (and often) asks to reinstall the app pretending the app would have been side loaded. This is happening with 1.1 and 1.2.

In-app updates disabled

This release was either side-loaded or downloaded using a browser in private mode.

Ignore | Reinstall app

In addition, I don't really get why we have this clunky sign in popin which really gets in the way. The experience on Hockey App was much better and stable for that matter.

guperrot commented 6 years ago

Hi, we never had this report before and has proven to be very stable for other people and our own apps, we would need you to call AppCenter.LogLevel = LogLevel.Verbose before AppCenter.Start in a release test build. Once issue is a reproduced, we need you to extract the device logs having AppCenter in it so we can analyze the issue.

guperrot commented 6 years ago

Hey! We haven't heard from you in a while so we'll assume your issue is fixed and go ahead and close this conversation. Should you still have questions, please don't hesitate to contact us again. Thanks!

sandorfr commented 6 years ago

No it’s absolutely not fixed. I just haven’t had the time to gather the logs you asked yet. On Wed 14 Feb 2018 at 12:04, Guillaume Perrot notifications@github.com wrote:

Hey! We haven't heard from you in a while so we'll assume your issue is fixed and go ahead and close this conversation. Should you still have questions, please don't hesitate to contact us again. Thanks!

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#issuecomment-365460434, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpo71dRx77-RsyWIJuLRnH3TTmvcSks5tUjEBgaJpZM4R5NHA .

guperrot commented 6 years ago

Ok, no problem, we will reopen the issue once we have logs.

sandorfr commented 6 years ago

Note that the problem is not reproductible on demand and so far happens over the air.

Fetching the logs you asked require the iPhone to be connected to an Mac with Xcode device utility running at the right moment.

Unless you have another way of getting the logs, I’m not sure I’ll manage to get them.

Can you point to place where you do this side loading check in your sdk? On Wed 14 Feb 2018 at 12:09, Guillaume Perrot notifications@github.com wrote:

Ok, no problem, we will reopen the issue once we have logs.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#issuecomment-365461489, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpr1P39Bf30qDyNnrPT0AOCi5awvUks5tUjJCgaJpZM4R5NHA .

guperrot commented 6 years ago

The backend is doing sideloading check, not SDK.

It works like this:

For first install you need to click on email or visit the install portal (not appcenter.ms but install.appcenter.ms) to download the application the first time.

When clicking on the download for a specific version, portal remembers you did download that specific version from portal (it uses a cookie).

When installed, the application launches the browser with appsecret and version as part of the parameters, if the install followed the download of the very same version then in-app updates are enabled once and for all and we get a token as redirection parameter (the browser redirects to the app with either failure or success with the token).

Upon every further launch, we call the API to check latest release silently with that token.

If you did not follow the flow (download from install portal then immediately install), then browser redirects to app with a failure message that we display (in app dialog) with option to reinstall app from portal.

Every install that does not follow this process is thus considered side-loading.


For code the xamarin SDK has nothing since we coded that in our Apple SDK and are using bindings for Xamarin and React Native (and further platforms later). So the code that is used is actually objective C: https://github.com/Microsoft/AppCenter-SDK-Apple/blob/master/AppCenterDistribute/AppCenterDistribute/MSDistribute.m

sandorfr commented 6 years ago

OK, so the app is indeed installed using the flow which you describe (using the email link and then in app updates). So it means that for some reason the token becomes invalid in some random cases.

guperrot commented 6 years ago

Then we really need the logs to see what happened as we never got such a report before and could not experience the issue ourselves.

sandorfr commented 6 years ago

I tried to reproduce it "on demand" and of course no luck with that. (I'll keep trying).

I post the healthy log as a reference: log-healthy-verbose.appcenter.txt.zip

sandorfr commented 6 years ago

Let me give a bit of background regarding the app. It's a B2B app. we switched recently from hockeyapp to appcenter. We use it to do the crash monitoring on all environments including the store and we are using it to distribute private 'in-house' apps to restricted groups.

The user in the restricted group are testers, developers but the most important ones are stakeholders who are not technical people. With hockeyapp they'd receive an email install the app once and then would have the update message when an update was available. No additionnal fuss.

Now with AppCenter, when they first launch the app they get a popup to turn on the notifications (will see to delay that bit) and then a message asking to sign in to turn on updates. Then when they say yes (why would they say no, and actually we don't want them to say no) they get this full screen page with a loader.

This is just confusing the user and degrading the experience. Add to that that the app lands on an actual login screen as it is a B2B app. and they get even more confused.

Don't get me wrong I love what's being done on AppCenter on many aspects, but this part is really annoying. What we would expect.

ElektrojungeAtWork commented 6 years ago

Hi @sandorfr,

Thank you for all the information about how you use App Center.

Now with AppCenter, when they first launch the app they get a popup to turn on the notifications (will see to delay that bit) and then a message asking to sign in to turn on updates. Then when they say yes (why would they say no, and actually we don't want them to say no) they get this full screen page with a loader.

The appearance of this popup is done automatically by iOS as soon as the SDK initializes push notification functionality. There is no way to circumvent this dialog. What could be done here is delaying initialization of the push functionality. I cannot think of a way where the SDK can do this "magically" at the right moment for all apps. What would you ideal API for this look like? (given that the dialog needs to pop up eventually)

Capability avoid having this popup asking the user to enable Updates. we turn them on for a reason. This is completely unnecessary.

You mention that you used HockeyApp in the past. Do you remember how you authenticated users against HockeyApp? The reason you see the popup is that we currently have public distribution of apps or private distribution which requires a login.

If you are more comfortable sharing this in private, feel free to shoot us an email to appcentersdk@microsoft.com or get in touch via Intercom (blue button in App Center portal at the bottom right once you are logged in) and mention this thread on GH and I'll get assigned to it.

Cheers and thanks for all the feedback! Benjamin

sandorfr commented 6 years ago

Hi @TroubleMakerBen,

Regarding the notification popup I'm well aware you can't do anything about it. However in the default setup where it pops up immediately it just adds to the mess. But browsing the issues here I noticed that it's as easy as splitting the Appcenter.Start intro several bits to delay that part.

I'm pretty sure there was no authentication on hockeyapp (or at least we didn't turn it on). In our case we don't see any benefit to adding a extra authentication layer. Don't get me wrong I understand that the download is always protected with a token is a security improvement. However since everything happens without any user interaction, there's no benefits to have the UI part of that interaction.

guperrot commented 6 years ago

We are working on a separate application that replaces the web site to manage installed apps from AppCenter. If that app is installed, it will be used instead of the browser for the authentication part, so people having the application will have a better experience.

sandorfr commented 6 years ago

That’s a great news which would solve 100% of my concerns regarding this!

sandorfr commented 6 years ago

After second thoughts. The new scenario is? I have app center app installed, I’m authenticated in it. I install one app. I launch that new install I’m redirected to the app center app to “enable updates” When done I’m switched back to the original app (Facebook style I guess)

If that’s the scenario I find it even worse. I still have the exact same problem.

guperrot commented 6 years ago

It's very quick and when I tested I didn't see any animation, it's as if I never left the app.

sandorfr commented 6 years ago

Ah in that case :) On Thu 15 Feb 2018 at 09:16, Guillaume Perrot notifications@github.com wrote:

It's very quick and when I tested I didn't see any animation, it's as if I never left the app.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#issuecomment-365763059, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpj8VDamIYiCZ4m9YXQVI-xzUc6Igks5tU1sggaJpZM4R5NHA .

guperrot commented 6 years ago

My comment was for Android in a specific device, iOS will have a very brief screen animation.

sandorfr commented 6 years ago

Mmmm.

One question why not just make this web view invisible? It seems others have done that with success :

https://stackoverflow.com/questions/15955798/ios-app On Thu 15 Feb 2018 at 09:27, Guillaume Perrot notifications@github.com wrote:

My comment was for Android in a specific device, iOS will have a very brief screen animation.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#issuecomment-365765935, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpjJclxiIj2h1xAhit9zHxZlH7chEks5tU13YgaJpZM4R5NHA .

ElektrojungeAtWork commented 6 years ago

(I love this discussion.)

So first, that SO post kinda contains the answer already. The experience is "like this by design" and I happily share the reasons for our decisions:

a) Invisible web views violate app store guidelines SafariViewContoller must be used to visibly present information to users; the controller may not be hidden or obscured by other views or layers. Additionally, an app may not use SafariViewController to track users without their knowledge and consent.

b) SFSafariViewController behavior changed with iOS 11 In iOS 10, SFSafariViewController can open within the app and read the cookies of Safari.app without user consent. iOS 11 changes the behavior. It's still possible to access a website's cookies but iOS presents an alert first and asks for a user's consent.

c) Back and forth between App Center App and your application I agree that this is somewhat clunky. My opinion is that we'll definitely need to think of ways to improve this. The overall way how we approach this is that we a) follow Apple's guidelines b) make sure we don't cause any rejection, ever, and c) try to strike a balance between transparency and convenience.

Overall, I agree that if you already require a login by users of your app, that they shouldn't have to enter yet another login information to get in-app-updates. What would be a valid option for you:

sandorfr commented 6 years ago

a) is sort of irrelevant to that case as I hardly see distribute being enabled in a production/AppStore version of the app.

b) I wasn't aware of b, it sucks. But as usual Apple rules :(

c) At a first glance

sandorfr commented 6 years ago

Regarding the logs, I finally got lucky (sort of) @guperrot: failing-log.txt.zip

JoshuaWeber commented 6 years ago

Hi @sandorfr. Thanks for having this chat with us. It is HUGELY informative. We are well aligned with your goals I think, we want to make the install and update experience as seamless as possible for end testers. I also agree with you, we aren't there yet.

We made some tradeoff design choices (the reasoning for lots of them is seen above). I think we have missed some of the scenarios and optimal support for your scenarios. We are currently working to re-think how we are doing some of this. Your feedback is very helpful to us to make sure we get it "right" during our next iteration.

I'm leaning towards the API approach. Alot of this non-ideal experience is us trying to work around a authentication flow. If we provided an API way for you as the dev to provide the authentication (just the email of the current user) we wouldn't need all this (as hockeyapp does it). I think we should add that option back in.

guperrot commented 6 years ago

@sandorfr did you use a public group url to install the app on last failure or were you logged in to install portal? Any chance you were using desktop site instead of install mobile site?

sandorfr commented 6 years ago

@guperrot I'm 99.9% sure I used the link from the email I received in my Outlook IOS App (with open links set to Safari). It led me to install.appcenter.ms. No sadly this is happening with the Collaborators distribution group.

If it's any help I may be able to give you access to it.

sandorfr commented 6 years ago

@JoshuaWeber No worries at all.

If we have to provide the email of the user it's not gonna work perfectly for us as they use test accounts which are different from their AppCenter credentials. The app is used in 6 countries today and people are switching accounts all the time to test under various parameters.

However I guess you need to that information to keep track of things like who installed the app?

Maybe we should have a call (or meet, I'll be in Seattle for the MVP summit) to talk this through.

JessicaYeh commented 6 years ago

@sandorfr Hello! Can you please try the following?

There's a known issue with strange local storage sync behavior between the main Safari app (where you install from and where we save cookies/local storage) and the UISafariViewController that pops up to enable in-app updates by reading those cookies/local storage. I want to see if we can rule that out, or if that's actually the cause of the update setup failure.

sandorfr commented 6 years ago

Will do (probably tomorrow in your time zone) On Fri 16 Feb 2018 at 12:00, Jessica Yeh notifications@github.com wrote:

@sandorfr https://github.com/sandorfr Hello! Can you please try the following?

  • uninstall your app (the one trying to enable in-app updates)
  • force quit Safari
  • reopen the install link in that email and install the app
  • see if in-app updates works now

There's a known issue with strange local storage sync behavior between the main Safari app (where you install from and where we save cookies/local storage) and the UISafariViewController that pops up to enable in-app updates by reading those cookies/local storage. I want to see if we can rule that out, or if that's actually the cause of the update setup failure.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#issuecomment-366114123, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpiVDkq_J2yaWir1DTAp2T99GgIGxks5tVNMOgaJpZM4R5NHA .

sandorfr commented 6 years ago

@JessicaYeh I did this and so far so good.

JessicaYeh commented 6 years ago

@sandorfr Great, thanks for testing that! We're going to make a small change in the next day or so that should fix the issue and remove the need to force quit Safari. No SDK update required on your side :) I'll post again once the change is deployed.

JoshuaWeber commented 6 years ago

@sandorfr I'd for sure like to meet up during the MVP Summit (I'm speaking at it and will be around). Can you send me an email at joshweb at microsoft dot com and I'll set up a chance for us to meet and chat face to face.

JessicaYeh commented 6 years ago

@sandorfr The fix is now live! Re-installing the app should no longer fail in-app updates. (just make sure to refresh the install site and maybe need to force quit Safari one last time)

guperrot commented 6 years ago

Hey!

We haven't heard from you in a while, so I am going to go ahead and close this conversation. Should you still have any questions, please don't hesitate to contact us again.

Thanks for using App Center!

sandorfr commented 6 years ago

Hi,

I'm afraid the issue is still happening :(. I've just faced it again :(

guperrot commented 6 years ago

Hi, do you have the SDK logs?

sandorfr commented 6 years ago

Hi @guperrot,

I suppose you need me to re-enable the verbose logs again?

guperrot commented 6 years ago

This is unfortunately the only way for us to see what could go wrong as we never reproduced the issues on our ios applications on real devices.

sandorfr commented 6 years ago

Hi sorry I didn't have the time to get back to you. I still see the problem happening. On of the problem to get the logs is that it currently requires to have the device connected to a mac. In other terms it requires me to be very lucky on when it happens.

Apparently there's a way to have IOS dump those logs into a file which can be retrieve afterwards. I'll give it a try (as it should affect all logs from any library). However you might consider adding an easy way to turn it on with the sdk.

ElektrojungeAtWork commented 6 years ago

Hi @sandorfr,

It's been a while since we heard from you. Any chance you were able to check with verbose logging?

ElektrojungeAtWork commented 6 years ago

I also feel like this issue contains a feature request:

"Add API in SDK to dump console logs into a file" as described in the SO link. I'd like to add an initial thought to this: The presented solution sounds convenient at first but allowing iTunes file sharing is not a thing to do lightly. Note: In the .plist file make sure that Application supports iTunes file sharing is exists and is set to YES so that you can access through iTunes.

sandorfr commented 6 years ago

Hi @TroubleMakerBen,

You are right there a feature request there :).

The problem has not magically disappeared but I haven't found the time to work on this, as some more critical subjects have priority (not that it does not matter). Sometimes you learn to live with a problem when there's bigger ones :D. I hope I'll have the next version properly instrumented so we can collect those files.

iamclement commented 6 years ago

Hey @sandorfr, have you found some times to collect those verbose logs?

sandorfr commented 6 years ago

The problem hasn't happened recently :(.

Just in case you need this kind of logs from anyone else here is the code I've added in my AppDelegate after turning on ITunes file sharing,

 [DllImport("/usr/lib/libc.dylib")]
        extern static IntPtr freopen([MarshalAs(UnmanagedType.LPStr)] string filename, [MarshalAs(UnmanagedType.LPStr)] string mode, IntPtr stream);

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
#if INHOUSE || DEBUG
            var paths = NSSearchPath.GetDirectories(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User, true);
            var documentsDirectory = paths[0];
            var logFileName = $"{documentsDirectory}/{DateTime.Now.ToString("yyyyMMdd")}.log";

            IntPtr libC = ObjCRuntime.Dlfcn.dlopen("/usr/lib/libc.dylib", 0);
            IntPtr stdErr = ObjCRuntime.Dlfcn.GetIntPtr(libC, "__stderrp");
            freopen(logFileName, "a+", stdErr);

            AppCenter.LogLevel = LogLevel.Verbose;
#endif

I'm closing it as I believe the UX problems mentioned above are well understood. I'm closing it for now, will reopen if I reproduce the problem and the log.

guperrot commented 6 years ago

Hi, thanks for getting back to us and sharing the logging code. We will reopen the issue if you have new elements for this thread and thanks for using App Center.

sandorfr commented 6 years ago

Hi @guperrot,

I've got this again. I sent some logs to Joshua as I had his email. Hope this will help you track it down :)

guperrot commented 6 years ago

Hi, Joshua is not available, if you want to share private logs, we should continue this discussion on https://appcenter.ms using the chat button, you can upload files there.

guperrot commented 6 years ago

@sandorfr thanks for the logs, as you can see above with the PR link we are pretty sure about the root cause thanks to the logs you shared. You can expect a release around mid July.

sandorfr commented 6 years ago

Great news, thanks :)

guperrot commented 6 years ago

The bug has been fixed and released in version 1.8.0.

sandorfr commented 6 years ago

Cool ! Thank you! I know what to do this weekend :) On Fri 20 Jul 2018 at 13:16, Guillaume Perrot notifications@github.com wrote:

Closed #597 https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597 .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/AppCenter-SDK-DotNet/issues/597#event-1743932611, or mute the thread https://github.com/notifications/unsubscribe-auth/ACiXpjyBzMJDq6BfG8rCDnE_yET5XqIqks5uIUuEgaJpZM4R5NHA .