Type 'Null' is not a subtype of type 'Widget'

Viewed 6665

I'm writing a code on flutter to Sign In with Google for both android/ios and web, but I got this error at the first hand. I run this on android emulator to check if it is working, I haven't set it for web right now. And after running on emulator I got the following error:

======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building Obx(has builder, dirty, state: _ObxState#c1649):
type 'Null' is not a subtype of type 'Widget'

The relevant error-causing widget was: 
  Obx Obx:file:///D:/Noum/Data/Uni%20Data/Codes/Android%20Studio/Flutter/web_ios_android_google_signin/lib/LoginPage.dart:13:15
When the exception was thrown, this was the stack: 
#0      LoginPage.build.<anonymous closure> (package:web_ios_android_google_signin/LoginPage.dart:16:19)
#1      Obx.build (package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart:70:28)
#2      RxInterface.notifyChildren (package:get/get_rx/src/rx_types/rx_core/rx_interface.dart:26:27)
#3      _ObxState.build (package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart:54:19)
#4      StatefulElement.build (package:flutter/src/widgets/framework.dart:4782:27)
#5      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4665:15)
#6      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4840:11)
#7      Element.rebuild (package:flutter/src/widgets/framework.dart:4355:5)
#8      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4643:5)
#9      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4831:11)
#184    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1143:15)
#185    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1080:9)
#186    SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:863:7)
(elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)
====================================================================================================

Flutter Doctor

D:\Noum\Data\Uni Data\Codes\Android Studio\Flutter\web_ios_android_google_signin\android>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel beta, 2.4.0-4.2.pre, on Microsoft Windows [Version 10.0.19043.1149], locale en-PK)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[√] Android Studio (version 4.2.0)
[√] Connected device (3 available)

• No issues found!

All dart files

Main.dart

import 'package:flutter/material.dart';
import 'package:get/get_navigation/src/root/get_material_app.dart';
import 'package:web_ios_android_google_signin/LoginPage.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(),
    );
  }
}

LoginController.dart

import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:get/get_state_manager/src/simple/get_controllers.dart';
import 'package:google_sign_in/google_sign_in.dart';

class LoginController extends GetxController{
 var _googleSignin=GoogleSignIn();
 var googleAccount=Rx<GoogleSignInAccount?>(null);

login() async{
  googleAccount = (await _googleSignin.signIn()) as Rx<GoogleSignInAccount?>;
}

 logOut() async{
   googleAccount = (await _googleSignin.signOut()) as Rx<GoogleSignInAccount?>;
 }

}

LoginPage

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:web_ios_android_google_signin/Login_Controller.dart';

class LoginPage extends StatelessWidget {
  //const LoginPage({Key? key}) : super(key: key);
final controller=Get.put(LoginController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Page')),
      body: Center(
       child: Obx((){
         if(controller.googleAccount.value==null)

           return buildLoginButton();

         else

           return buildProfileView();

       }
       ),
       )
        );
  }

  buildProfileView(){
    Column(
        mainAxisSize: MainAxisSize.min,
        children: [
        CircleAvatar(
        backgroundImage: Image.network(controller.googleAccount.value?.photoUrl ?? '').image,
    radius: 100,
    ),
    Text(
        controller.googleAccount.value?.displayName ?? '',
      style: Get.textTheme.headline3,
    ),
    Text(
        controller.googleAccount.value?.email ?? '',
      style: Get.textTheme.bodyText1,
    ),
          SizedBox(height: 16),
          ActionChip(
            avatar: Icon(Icons.logout),
              label: Text('Logout'),
              onPressed: (){
              controller.logOut();
              },
          )
    ],
    );
  }




  buildLoginButton(){
    FloatingActionButton.extended(
      onPressed: (){
        controller.login();
      },
      icon: Image.asset(
        'images/googlepnglogo',
        height: 32,
        width: 32,
      ),
      label: Text('SignIn With Google'),
      backgroundColor: Colors.white,
      foregroundColor: Colors.black54,
    );
  }
}
3 Answers

Add Your methods using return keywords like below hope it help you:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:web_ios_android_google_signin/Login_Controller.dart';

class LoginPage extends StatelessWidget {
  //const LoginPage({Key? key}) : super(key: key);
final controller=Get.put(LoginController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Login Page')),
      body: Center(
       child: Obx((){
         if(controller.googleAccount.value==null)

           buildLoginButton();

         else

           buildProfileView();

       }
       ),
       )
        );
  }

  buildProfileView(){
    return Column(
        mainAxisSize: MainAxisSize.min,
        children: [
        CircleAvatar(
        backgroundImage: Image.network(controller.googleAccount.value?.photoUrl ?? '').image,
    radius: 100,
    ),
    Text(
        controller.googleAccount.value?.displayName ?? '',
      style: Get.textTheme.headline3,
    ),
    Text(
        controller.googleAccount.value?.email ?? '',
      style: Get.textTheme.bodyText1,
    ),
          SizedBox(height: 16),
          ActionChip(
            avatar: Icon(Icons.logout),
              label: Text('Logout'),
              onPressed: (){
              controller.logOut();
              },
          )
    ],
    );
  }




  buildLoginButton(){
    return FloatingActionButton.extended(
      onPressed: (){
        controller.login();
      },
      icon: Image.asset(
        'images/googlepnglogo',
        height: 32,
        width: 32,
      ),
      label: Text('SignIn With Google'),
      backgroundColor: Colors.white,
      foregroundColor: Colors.black54,
    );
  }
}

You forgot to add return in below methods

buildProfileView(){
   return Column();
}
buildLoginButton(){
   return FloatingActionButton.extended()
}
    import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:web_ios_android_google_signin/Login_Controller.dart';

class LoginPage extends StatelessWidget {
  //const LoginPage({Key? key}) : super(key: key);
  final controller=Get.put(LoginController());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Login Page')),
        body: Center(
          child: Obx((){
            (controller.googleAccount.value==null)?
            child1:child2;
          }
          ),
        )
    );
  }

  Widget child1 = Column(
    mainAxisSize: MainAxisSize.min,
    children: [
      CircleAvatar(
        backgroundImage: Image.network(controller.googleAccount.value?.photoUrl ?? '').image,
        radius: 100,
      ),
      Text(
        controller.googleAccount.value?.displayName ?? '',
        style: Get.textTheme.headline3,
      ),
      Text(
        controller.googleAccount.value?.email ?? '',
        style: Get.textTheme.bodyText1,
      ),
      SizedBox(height: 16),
      ActionChip(
        avatar: Icon(Icons.logout),
        label: Text('Logout'),
        onPressed: (){
          controller.logOut();
        },
      )
    ],
  );

  Widget child2 = FloatingActionButton.extended(
    onPressed: (){
      controller.login();
    },
    icon: Image.asset(
      'images/googlepnglogo',
      height: 32,
      width: 32,
    ),
    label: Text('SignIn With Google'),
    backgroundColor: Colors.white,
    foregroundColor: Colors.black54,
  );
}
Related