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

[go_router] Expose full Uri on GoRouterState in GoRouterRedirect #5742

Merged
merged 15 commits into from
Feb 9, 2024

Conversation

ChopinDavid
Copy link
Contributor

A number of developers have voiced the desire to be able to know whether a GoRouterState is the result of a deep-link or in-app navigation from within their GoRouter's redirect method. This can be accomplished by exposing the Uri's scheme and host on the GoRouterState. This way, we can know whether the GoRouterState is the result of a deep-link by checking state.uri.scheme != null or state.uri.host != null.

This PR would close #103659.

No tests were broken as a result of this change, and we have added coverage for this change through new tests.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the package surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Copy link

google-cla bot commented Dec 22, 2023

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ChopinDavid
Copy link
Contributor Author

@SuperWes It seems Dan would need to sign the Google CLA to pass all checks as the first commit of this PR was authored by him. See here.

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are migrating to uri, can you double check every place with todo linked with flutter/flutter#124045 ?

@@ -86,7 +86,8 @@ class GoRouteInformationParser extends RouteInformationParser<RouteMatchList> {
// to uri, empty path check might be required here; see
// https://github.com/flutter/packages/pull/5113#discussion_r1374861070
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire todo and ignores above can be removed, and we need to do empty path check here as well per comment above

Copy link
Contributor Author

@ChopinDavid ChopinDavid Dec 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire todo and ignores above can be removed, and we need to do empty path check here as well per comment above

I am not sure that we necessarily need to do the empty path check. It seems that you feel we need to do this check so that we do not re-introduce Issue #133928. But when launching our company's app through a deep link with no path (https://www.wwt.com) from a "dead" state, we are not seeing this GoException: no routes for location error message and the app launches as expected.

Maybe you can check to see if this issue has been re-introduced on your side?

Or, was there maybe another reason why we felt we had to add the empty path check other than re-introducing Issue #133928?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me check and I will get back to you

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am testing in android, it looks like when cold start without the path the uri doesn't contain the host name and scheme. I am not sure what happen here.

If I warm start without the path, it would show no route for location. It seems to me we need to handle empty path here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for code start, it is going through this code path

// TODO(chunhtai): Clean up this once `RouteInformation.uri` is available

this need to be migrated as well

Copy link
Contributor Author

@ChopinDavid ChopinDavid Dec 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I am actually seeing that we get the no routes for location error when launching www.domain.com while the app is already running in the background.

It's almost as if we need to treat all www.domain.com URIs as www.domain.com/ so that the location defaults to /. It makes sense that having an empty-string location wouldn't match anything.

For context, I am looking here, where no match is found for an empty string, even for the / path. It maybe makes sense to have an empty-string location redirect to the GoRouter's initialLocation.

Does this make sense, or is there a better approach? This still doesn't, for me, explain why we don't get the no routes for location error when launching www.domain.com while the app is not running in the background.

Copy link
Contributor Author

@ChopinDavid ChopinDavid Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chunhtai Does this sound like the right approach to you? Nevermind, we think we found the right approach, new commit imminent.

Copy link
Contributor Author

@ChopinDavid ChopinDavid Jan 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chunhtai we went ahead and added the empty path check to ensure that routeInformation with an empty .uri.path has a / appended to the end of it. This behavior matches what we had previously been doing with routeInformation.location.

The issue is that there are a few tests (3) failing now. It seems like some of these tests could be rewritten to accommodate for the changes we've made, but we are hesitant to do this in fear of breaking functionality for others...

Let me know what you think is a good path forward for this.

@ChopinDavid
Copy link
Contributor Author

@chunhtai I went ahead and migrated all occurrences of RouteInformation.location per the migration guide. I did have a few questions:

  • It seems that this TODO can go ahead and be removed?
  • I went ahead and removed the didPushRoute override entirely from InformationProvider. Does this sound correct?

@@ -109,7 +105,7 @@ class GoRouteInformationProvider extends RouteInformationProvider
final bool replace;
switch (type) {
case RouteInformationReportingType.none:
if (_valueInEngine.location == routeInformation.location &&
if (_valueInEngine.uri.path == routeInformation.uri.path &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also need to check the query parameter and hash fragment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So something like

if (_valueInEngine.uri.path == routeInformation.uri.path &&
            _valueInEngine.uri.queryParameters ==
                routeInformation.uri.queryParameters &&
            _valueInEngine.uri.fragment == routeInformation.uri.fragment &&
            const DeepCollectionEquality()
                .equals(_valueInEngine.state, routeInformation.state))

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably need to do collection equality for query parameter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I have done these correctly, I went ahead and added DeepCollectionEquality checks to the queryParameters and fragments, as well as the paths and states.

@@ -149,8 +142,8 @@ class GoRouteInformationProvider extends RouteInformationProvider

void _setValue(String location, Object state) {
final bool shouldNotify =
_value.location != location || _value.state != state;
_value = RouteInformation(location: location, state: state);
_value.uri.path != location || _value.state != state;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here this should also account for query parameter and hashfragment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above ⬆️, believe these have been fixed but let me know if you think otherwise.

@@ -86,7 +86,8 @@ class GoRouteInformationParser extends RouteInformationParser<RouteMatchList> {
// to uri, empty path check might be required here; see
// https://github.com/flutter/packages/pull/5113#discussion_r1374861070
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me check and I will get back to you

@chunhtai
Copy link
Contributor

@chunhtai I went ahead and migrated all occurrences of RouteInformation.location per the migration guide. I did have a few questions:

  • It seems that this TODO can go ahead and be removed?

It seems so, yes can you try to remove it and see if the analyzer complains or not

  • I went ahead and removed the didPushRoute override entirely from InformationProvider. Does this sound correct?

That sounds correct.

@chunhtai
Copy link
Contributor

looks like the CLA is not signed, this can happen if the commit history contain too many unrelated commit, you probably should do a sqush and force push, or just reset

@ChopinDavid
Copy link
Contributor Author

looks like the CLA is not signed, this can happen if the commit history contain too many unrelated commit, you probably should do a sqush and force push, or just reset

The first commit on this branch was made by another member of my team. He probably just needs to sign the CLA. I will check with him in the coming days.

@ChopinDavid
Copy link
Contributor Author

@chunhtai We believe we have this in a good state. We ensured all tests are passing (without modifying said tests) and added new tests to cover the changes that were made.

Please let me know if you are unsure about any of these changes. Would love to see this get merged in!

@ChopinDavid ChopinDavid force-pushed the Issue103659 branch 2 times, most recently from 029a273 to a84020e Compare January 8, 2024 21:26
final bool shouldNotify =
_value.location != location || _value.state != state;
_value = RouteInformation(location: location, state: state);
!deepCollectionEquality.equals(_value.uri.path, uri.path) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code here is duplicated to above, extract it to a function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved via 5597ddb

Please, let me know if this does not look right to you.

@@ -274,11 +278,4 @@ class GoRouteInformationProvider extends RouteInformationProvider
_platformReportsNewRouteInformation(routeInformation);
return SynchronousFuture<bool>(true);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why remove this?

Copy link
Contributor Author

@ChopinDavid ChopinDavid Jan 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hellohuanlin hellohuanlin removed their request for review January 16, 2024 19:35
@bawahakim
Copy link

FWIW, works well for me (at least on Android), and looking forward to having this in release, thanks @ChopinDavid ! 🚀

@ZanderZhan
Copy link

Works well for me too, it's good having this in release as soon as possible, thanks @ChopinDavid ! 🚀

@hangyujin
Copy link
Contributor

@ChopinDavid can you resolve the conflicts for this PR so it can be merged ?

@hangyujin
Copy link
Contributor

@johnpryan can you take a second look at this PR since chun-heng is on vacation?

@ChopinDavid
Copy link
Contributor Author

ChopinDavid commented Feb 8, 2024

Hi guys, I will resolve these conflicts a bit later today. Thanks for the help everyone! 🙂🚀

@ChopinDavid
Copy link
Contributor Author

Looks like everything should be good to go now

@hangyujin hangyujin added the autosubmit Merge PR when tree becomes green via auto submit App label Feb 9, 2024
@auto-submit auto-submit bot merged commit c269727 into flutter:main Feb 9, 2024
78 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Feb 12, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Feb 12, 2024
flutter/packages@11152d2...0a69259

2024-02-09 everythingoutdated@gmail.com [local_auth]: Renamed `local_auth_ios` to `local_auth_darwin` (flutter/packages#5809)
2024-02-09 ltv.luongthevinh@gmail.com [webview_flutter] Add listener for content offset (flutter/packages#3444)
2024-02-09 David.Chopin@wwt.com [go_router] Expose full `Uri` on `GoRouterState` in `GoRouterRedirect` (flutter/packages#5742)
2024-02-09 stuartmorgan@google.com [webview_flutter] Minor test cleanup (flutter/packages#6031)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages-flutter-autoroll
Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
arc-yong pushed a commit to Arctuition/packages-arc that referenced this pull request Jun 14, 2024
flutter#5742)

A number of developers have voiced the desire to be able to know whether a `GoRouterState` is the result of a deep-link or in-app navigation from within their `GoRouter`'s `redirect` method. This can be accomplished by exposing the `Uri`'s `scheme` and `host` on the `GoRouterState`. This way, we can know whether the `GoRouterState` is the result of a deep-link by checking `state.uri.scheme != null` or `state.uri.host != null`.

This PR would close [#103659](flutter/flutter#103659 (comment)).

No tests were broken as a result of this change, and we have added coverage for this change through new tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App p: go_router
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[go_router] Prevent access to route when navigated to via a deep link
7 participants