invertase / flutter_desktop_webview_auth

WebView OAuth flows for desktop flutter apps
Apache License 2.0
34 stars 35 forks source link

Windows app crashes after login #56

Open thecodekitchen opened 6 months ago

thecodekitchen commented 6 months ago

After building my project in Windows, activating the web view, and entering auth information, I am very briefly returned to the application, but it immediately shuts down with no error message other than 'Lost connection to device'.

dependencies from pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  firebase_auth: ^4.19.1
  firebase_core: ^2.29.0
  http: ^0.13.6
  desktop_webview_auth: ^0.0.12

main.dart

import 'package:desktop_webview_auth/google.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:desktop_webview_auth/desktop_webview_auth.dart';
import 'package:http/http.dart' as http;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? _accessToken;
  String? _email;
  String? _response;
  String? _error;
  GoogleSignInArgs args = GoogleSignInArgs(
    clientId:
        '<MY_CLIENT_ID>',
    redirectUri: "https://<MY_PROJECT>.firebaseapp.com/__/auth/handler",
  );
  StreamSubscription? _sub;

  Future<void> googleSignIn() async {
    final result = await DesktopWebviewAuth.signIn(args);
    if (result != null) {
      OAuthCredential googleCred =
          GoogleAuthProvider.credential(accessToken: result.accessToken);
      await FirebaseAuth.instance.signInWithCredential(googleCred);
    } else {
      setState(() => _error = 'Google Sign In failed');
      print('Failed to authenticate');
    }
  }

  @override
  void initState() {
    FirebaseAuth.instance.authStateChanges().listen((User? user) {
      if (user != null) {
        String? token;
        user.getIdToken().then((value) {
          token = value;
          setState(() {
            _email = user.email;
          });
          if (token != null) {
            setState(() {
              _accessToken = token;
            });
          }
        });
      }
    });
    super.initState();
  }

  @override
  void dispose() {
    _sub?.cancel();
    super.dispose();
  }

  Future<void> callBackend() async {
    if (_accessToken == null) {
      setState(() {
        _response = 'Access token is null';
      });
    } else {
      final response = await http.get(
        Uri.parse('http://localhost:8080/ping'),
        headers: <String, String>{
          'Authorization': 'Bearer $_accessToken',
        },
      );
      if (response.statusCode == 200) {
        setState(() {
          _response = response.body;
        });
      } else {
        setState(() {
          _response = 'Failed to call backend';
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: const Text('Firebase Login'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                onPressed: googleSignIn,
                child: const Text('Sign in with Google'),
              ),
              if (_accessToken != null)
                Text('Access Token: $_accessToken\nEmail: $_email'),
              ElevatedButton(
                  onPressed: callBackend, child: const Text('Call Backend')),
              if (_response != null) Text('Response: $_response'),
              if (_error != null) Text('Error: $_error'),
            ],
          ),
        ));
  }
}