flutter firebase streambuilder gives returned null error

2.2k views Asked by At

I am trying to read data realtime from my firebase firestore database through flutter. I learned that the best way to manage this is streambuilder. Checked a few sites on this topic and made a code like below and put a print statement just to see if everything works ok, however when i run the program it give the fallowing errors:

A build function returned null.
The relevant error-causing widget was: 
  StreamBuilder<DocumentSnapshot> file:///C:/Users/faruk/Desktop/3-sayiavi/sayi_avi/lib/gamescreen.dart:116:15

The method '[]' was called on null.
Receiver: null
Tried calling: []("status")
The relevant error-causing widget was: 
  StreamBuilder<DocumentSnapshot> file:///C:/Users/faruk/Desktop/3-sayiavi/sayi_avi/lib/gamescreen.dart:116:15

My Code is below:

    import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  FirebaseUser loggedInUser;
  final _firestore = Firestore.instance;
  String collectionPath = 'users';
  String docPath;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }
  
  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser();
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
        print(docPath);
        print(collectionPath);
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
      //todo: _auth.signOut(); ekleyerek signout yapacaz
      //Navigator.pop(context); bir önceki ekrana dönecez;
    );
  }





  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder(
          stream: _firestore.collection(collectionPath).document(docPath).snapshots(),
          builder: (context,snapshot){
            if(snapshot.hasData){
              var userDocument = snapshot.data;
              print(userDocument['status']);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}

changed the code like this:

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  FirebaseUser loggedInUser;
  final _firestore = Firestore.instance;
  String collectionPath = 'users';
  String docPath;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }

  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser();
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
        print(docPath);
        print(collectionPath);
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
      //todo: _auth.signOut(); ekleyerek signout yapacaz
      //Navigator.pop(context); bir önceki ekrana dönecez;
    );
  }





  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder<DocumentSnapshot>(
          stream: _firestore.collection(collectionPath).document(docPath).snapshots(),
          builder: (BuildContext context,AsyncSnapshot<DocumentSnapshot> snapshot){
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Text("Loading");
            }
            if(snapshot.hasData){
              Map<String, dynamic> userDocument  = snapshot.data.data;
              print(userDocument);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}

Currently it gets the values of the map when i click save button, but when i go back and forward in the avd it gets null again. What may be wrong?

what i would like to do is, there is a firebase function which matches users according to their "status" in the database. when a user enters this screen, its status will be "on" in the database and when firebase function finds another user with "on" status it will make both their status "ready" or something like this. When the user's status changed to "ready" instead of showing a for example "searching for a match" screen it will change to game screen and 2 ppl will start to play turn based. So to sum up as soon as user enters this screen it should start to listen changes in its status. Also as it will be a turn based game it should continue to listen other fields later for database changes. I hope i could have explained myself.

Updated the flutter firebase code for new dependencies below

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  User loggedInUser;
  final _firestore = FirebaseFirestore.instance;
  final String collectionPath = 'users';
  String docPath;
  DocumentReference userdoc;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }


  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser;
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
    );
  }




  @override
  Widget build(BuildContext context) {
    userdoc = _firestore.collection(collectionPath).doc(docPath);
    return StreamBuilder<DocumentSnapshot>(
      stream: userdoc.snapshots(),
      builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }
        if(snapshot.hasData){
          Map<String, dynamic> userDocument  = snapshot.data.data();
          print(collectionPath);
          print(docPath);
          print(snapshot.data);
          print(userDocument);
          return MaterialApp(
            home:Scaffold(
              appBar: AppBar(
                backgroundColor: Colors.amberAccent,
                title: Text('Sayı Avı Oyun Ekranı'),
              ),
              body:Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      },
    );
  }
}

You can see there are 4 prints to check if i am getting the data correctly. Currently when i run the app it shows

I/flutter (15703): users I/flutter (15703): viPK8SpL9MOIV2bQqGzBkKVdYAk2 I/flutter (15703): Instance of 'DocumentSnapshot' I/flutter (15703): null

The 4th one shouldnt supposed to be null, when i click "save" button in android studio i get

I/flutter (15703): users I/flutter (15703): viPK8SpL9MOIV2bQqGzBkKVdYAk2 I/flutter (15703): Instance of 'DocumentSnapshot' I/flutter (15703): {password: 123456, lose: 0, win: 0, email: [email protected], status: ready}

Which is the correct result.

4

There are 4 answers

3
Tirth Patel On

You forgot to call data() on snapshots()'s result in StreamBuilder.

var userDocument = snapshot.data.data();

Refer this: https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes

13
ahmed On

first you should call the initState then dispose it. because every time that you run the page or update it you will call the initState() and that is why you lose all the data again maybe. the code is like this:

  void initState() {
    super.initState();
   getCurrentUser();
  }

  @override
  void dispose() {
    // : implement dispose
   getCurrentUser();
    super.dispose();
  }

if that didn't help read this code. i had this problem because of QuerySnapshot and DocumentSnapShot

 StreamBuilder<QuerySnapshot>(

        stream: Firestore.instance.collection("MyTodos").snapshots(),

        builder: (context, snapshots) {

          return ListView.builder(
            shrinkWrap: true,
            addAutomaticKeepAlives: true,
            itemCount: snapshots.data.documents.length,
           
            itemBuilder: (BuildContext context, int index) {

              DocumentSnapshot documentSnapshot =
                  snapshots.data.documents[index];

              return Card(              
                  margin: EdgeInsets.all(6),
                  elevation: 2.0,
                  child: ListTile(
                  title: Text(documentSnapshot.data["todoTitle"]),                     
                  ),               
              );
            },
          );
        },
      ),

according to you error .I changed your code to this and you can find more on this link https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes

@override
  Widget build(BuildContext context) {
final users = _firestore.collection(collectionPath).document(docPath);
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder<QuerySnapshot>(
          stream: users.snapshots(),
          builder: (BuildContext context,AsyncSnapshot<QuerySnapshot> snapshot){
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Text("Loading");
            }
            if(snapshot.hasData){
              Map<String, dynamic> userDocument  = snapshot.data.documents;
              print(userDocument);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}
2
Taif Raoof On

I think when you Back to previous screen the initState and getCurrentUser() function is not call again and docPath is null so you should call this function from Build or make another way to call it and get docPath

0
Faruk On

After trying ahmed's answers and not having a solution i decided to rearrange my code just like here https://firebase.flutter.dev/docs/overview and it finally worked. Also upgraded all of my dependencies.

Here is my final code:

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}

class GameScreen extends StatefulWidget {
  static String id ='gamescreen';

  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  bool _initialized = false;
  bool _error = false;

  void initializeFlutterFire() async {
    try {
      // Wait for Firebase to initialize and set `_initialized` state to true
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch(e) {
      // Set `_error` state to true if Firebase initialization fails
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
    getCurrentUser();
  }

  final _auth =FirebaseAuth.instance;
  User loggedInUser;
  final _firestore = FirebaseFirestore.instance;
  final String collectionPath = 'users';
  String docPath;
  DocumentReference userdoc;


  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser;
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
    );
  }




  @override
  Widget build(BuildContext context) {
    userdoc = _firestore.collection(collectionPath).doc(docPath);
    if(_error) {
      return Text('error-game', textDirection: TextDirection.ltr);
    }

    // Show a loader until FlutterFire is initialized
    if (!_initialized) {
      return Text('Loading', textDirection: TextDirection.ltr);
    }
    return StreamBuilder<DocumentSnapshot>(
      stream: userdoc.snapshots(),
      builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }
        if(snapshot.hasData){
          Map<String, dynamic> userDocument  = snapshot.data.data();
          print(collectionPath);
          print(docPath);
          print(snapshot.data);
          print(userDocument);
          return MaterialApp(
            home:Scaffold(
              appBar: AppBar(
                backgroundColor: Colors.amberAccent,
                title: Text('Sayı Avı Oyun Ekranı'),
              ),
              body:Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      },
    );
  }
}