babincc / flutter_workshop

This repo houses add-ons, plug-ins, and helpful code to make Flutter programming easier.
5 stars 1 forks source link

demo not working ? [flutter_hue] #9

Open tempo-riz opened 1 year ago

tempo-riz commented 1 year ago

Hey I just cloned your repo to try the demo, the only modifications I did was replacing the placeholders with the clientId, clientSecret that I got from dev console and redirectUri with https://oauth.pstmn.io/v1/browser-callback

When I try the app, on my physical or emulated android. First I tried to call discoverBridges() (via the button) and I get the following output without anything else happening :

E/Dart    (28945): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android.
E/Dart    (28945): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android.
E/Dart    (28945): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android.
E/Dart    (28945): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android.

I tried the official philps hue app and everything works as expected with it I got a bridge with a play kit link

Thank you for developping this plugin, hope you can help !

tempo-riz commented 1 year ago

edit : apparently it does work but one time on 5-6 tries, then I established remote contact succesfully (so it seems) and the fetch Network button throws _TypeError (type '_Map<String, dynamic>' is not a subtype of type 'List<dynamic>?' in type cast) at await hueNetwork?.fetchAll();

babincc commented 1 year ago

The redirectUri is what you put in your Hue dev console when you made your account. It should be formatted like this [scheme]://[domain] - Example flutterhue://auth

This is used on Philips Hue's side when the user tells Hue that your app has permission to log into their account. Once they log in and approve your app, Philips Hue redirects them to the redirect URI from your dev console; your app will capture that redirect with deep linking and open your app.

Does this help at all?

tempo-riz commented 1 year ago

Yes, but the url I provided isn't valid ? I think it is with sheme being https, correct me if I'm wrong, my question was mostly related to the errors I got !

babincc commented 1 year ago

What is the URL you provided? Is that a Postman testing environment? Or is that what you would use in your final product?

Also, what are you trying to get your app to do right now? Are you trying to establish a remote connection (your phone not on the same network as your Philips Hue device) or a local connection (everything on the same wifi)?

tempo-riz commented 1 year ago

https://oauth.pstmn.io/v1/browser-callback Yes the public postman oauth, I think I can use it, at least for testing it should work, I can get the params from url

babincc commented 1 year ago

Are you familiar with deep linking? I'm not sure Postman is the right thing to use in this situation.

tempo-riz commented 1 year ago

My goal is to control my lights, Both with and without remote connection, for now none of the 2 methods are working, maybe I'm missing something ?

tempo-riz commented 1 year ago

When you run your example with latest flutter sdk and android version is it working for you?

babincc commented 1 year ago

Yes, it is working for me. Is your app running on a device that is on the same network as your Philips Hue bridge?

tempo-riz commented 1 year ago

Are you familiar with deep linking? I'm not sure Postman is the right thing to use in this situation.

Not really, If you have any ressource to link maybe it could help, thanks :)

babincc commented 1 year ago

Are you familiar with deep linking? I'm not sure Postman is the right thing to use in this situation.

Not really, If you have any ressource to link maybe it could help, thanks :)

Here is a link for deep linking in general https://docs.flutter.dev/ui/navigation/deep-linking

This is a link for setting up a remote connection with this SDK. The SDK should handle the deep linking for you https://github.com/babincc/flutter_workshop/blob/master/packages/flutter_hue/remote_connection_instructions.md

tempo-riz commented 1 year ago

Yes, it is working for me. Is your app running on a device that is on the same network as your Philips Hue bridge?

Yes the bridge with ethernet and my phone on wifi, I will do more testing tomorrow thanks for the docs

tempo-riz commented 1 year ago

okay so I tried with a new redirect uri, I updated it in hue's dev console, Tell me if something seems wrong to you :

this is my app id : com.example.jdr_ia so i used it like this in my manifest

and my redirect uri : "com.example.jdr_ia://auth"

I can detect my bridge with "discover bridges" button, then I can "first contact" then I tried 2 things :

  • directly "fetch network" (if I want to connect without remote connection, is that right ?) which throws this
    E/flutter (23538): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type '_Map<String, dynamic>' is not a subtype of type 'List<dynamic>?' in type cast
    E/flutter (23538): #0      new EntertainmentConfiguration.fromJson (package:flutter_hue/domain/models/entertainment_configuration/entertainment_configuration.dart:69:45)
    E/flutter (23538): #1      HueNetwork.fetchAllType (package:flutter_hue/domain/models/hue_network.dart:459:49)
    E/flutter (23538): <asynchronous suspension>
    E/flutter (23538): #2      HueNetwork.fetchAll (package:flutter_hue/domain/models/hue_network.dart:309:7)
    E/flutter (23538): <asynchronous suspension>
  • "establish remote connection" which opens the official hue app and asks permission, when I accept promp it doesnt redirect to my app but stay in hue (official)
babincc commented 1 year ago

directly "fetch network" (if I want to connect without remote connection, is that right ?) which throws this

I have published a new version (1.2.1) that should fix the above issue. You are testing my code with Philips Hue devices that I don't have. You may run into other bugs like this that I missed because I just never came across them in testing. Please let me know about them so I can get them fixed.

"establish remote connection" which opens the official hue app and asks permission, when I accept promp it doesnt redirect to my app but stay in hue (official)

This issue could be a number of things. The first thing I would do is stop your app emulation, run flutter clean in the console, and then flutter pub get. Then, start your app back up and see if it works. Deep linking can be a little tricky and when you change your Android manifest, it often times needs to be cleaned and rebuilt.

If that doesn't work, it could be the underscore in your URL scheme. It should work, but some people warn of odd behavior with special characters.

Try these ideas, and come back to me if it still isn't working. I'm happy to help!

tempo-riz commented 1 year ago

Thank you for your time and quick response !

The 1.2.1 fixed the fetchNetwork, now I can control the lamps locally !

I updated my scheme, which is now correctly redirecting to my app, it was probably an underscore issue.

I still have 2 issues :

  1. The discover bridges fonction only work once, when I install the app, after this it returns empty array, is that expected behavior ? I have to reinstall the app to make it work once again I don't know if related but I get the following error messages in both cases :

E/Dart (10226): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android. E/Dart (10226): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android. E/Dart (10226): Dart Socket ERROR: ../../third_party/dart/runtime/bin/socket_android.cc:147: `reusePort` not supported for Android.

  1. When I try to connect remotely, when redirected to my app, it doesn't seem to trigger in the uriLinksStream.listen()

I checked that with prints/breakpoint that never got triggered, it should after the redirect ? Or am I wrong ?

babincc commented 1 year ago

Once a bridge has been connected to, it will not show up again when discovering bridges. To find bridges that you have already connected to, use fetchSavedBridges().

I'm not sure why uriLinksStream.listen() wouldn't be called. Is your code public so I can look at it?

tempo-riz commented 1 year ago

okay fetchSavedBridges() works, I thougt maintain() and maintainBridges() were already calling it

for the stream.listen() I created a minimal example based on your example here

babincc commented 1 year ago

I don't see why it wouldn't be working for you. A few questions:

tempo-riz commented 1 year ago
babincc commented 1 year ago

After a lot of experimenting, I believe this line is causing your uriLinkStream.listen() not to be called:

<uses-permission android:name="android.permission.INTERNET" />

It is the second line in your Android manifest. Remove that line entirely, and run flutter clean and flutter pub get; then when you start up your app, it should work.

tempo-riz commented 1 year ago

I tried removing the line from manifest, runned flutter clean, flutter pub get, uninstalled app from my phone flutter run i'm on wifi, sucessfully first contact then tried to establish remote contact and listen() is still not triggered...

does it work for you ? on what device ?

babincc commented 1 year ago

It works for me on all devices.

If you just do a local connection, are you able to control the lights?

Can you try remote connection again, and give me the whole console printout?

tempo-riz commented 1 year ago

Locally yes, everything works as expected, I can use all the features showcased in the demo.

sure, here is the console output logs.txt

babincc commented 1 year ago

I don't see anything obvious to me. I do see this error:

E/flutter (18210): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Bad state: No element
E/flutter (18210): #0      List.first (dart:core-patch/growable_array.dart:343:5)
E/flutter (18210): #1      _HomePageState.fetchSavedBridges (package:playground/main.dart:408:62)
E/flutter (18210): <asynchronous suspension>

That could have something to do with it. Also, it is possible some other package is intercepting your incoming deep link.

If you are plugging the Flutter Hue SDK into your app that has lots of other code and packages, the best thing to do is work on a separate app that is just like the example app. Then, if you can get that working, add more to it until you find out what breaks it.

tempo-riz commented 1 year ago

I think this error might be because I tried to call fetchSavedBridges on a fresh install so there was no bridge saved...

To be 100 % sure it's not related to others packages i'm still using this repo to make my tests

tempo-riz commented 1 year ago

Do you have the official philips hue app or does the redirect opens your web browser ?

babincc commented 1 year ago

The redirect should open in your browser.

tempo-riz commented 1 year ago

Okay so I just tried to uninstall the philips hue app and it seems that it was because of it. when I had the app the prompt was opening in this app and callback not triggered after it now that I dont have it anymore prompt opens in browser and callback works.

It is still problematic tho, because most of philips hue users have the app...

tempo-riz commented 1 year ago

A solution for this could be to use webview to handle the auth process, this way we never leave the app in the first place !

tempo-riz commented 1 year ago

I tried using webview, it works but the google sign in doesnt...

tempo-riz commented 1 year ago

I tried use a web callback for example : https://oauth.pstmn.io/v1/browser-callback then the user would copy/paste to retrieve the params. but another intresting thing happens, maybe it is intended i'm not an expect on the topic...

I dont get a pcke code when redirect is opened in philip hue's app : this is how the parameters look without the app : /callback/?source=app&state=...&code=... and when redirected via the app (opens hue's app then browser on succes) /callback/?pkce=...&code=...&state=...

If you have an explanation of this don't hesitate !

babincc commented 11 months ago

I have looked extensively into this. Everything works as expected if the Hue app is not installed on the user's device. If the Hue app is installed, it intercepts the URL; in this case, remote access is granted, but it cannot send the user back to your app. This issue is on Philips Hue's end, and I cannot think of a way around it. If the user is not sent back to your app, it doesn't receive the token, and cannot use the remote access that it has been granted. I've reached out to Philips Hue for this issue and others I have had, and I have never gotten a response. I fear that they are not putting any resources into helping third-party developers, and we are on our own.

tempo-riz commented 11 months ago

Thank you for looking into it ! yeah the redirect doesnt work as expected, so I tried to use web callback instead of redirecting to my app, which works but as previously said the pkce is not present in response, is it mandatory ? If not how do I disable it ?

babincc commented 11 months ago

Yes the pkce is mandatory. It is how Philips Hue and your app confirm they are talking to each other. It prevents certain attacks.