Check if Field Already exists in Flutter Firestore

前端 未结 4 1848
隐瞒了意图╮
隐瞒了意图╮ 2020-12-15 00:47

I have a collection called company. All the companies are going to be stored like in my screenshot.

When I add another company, I want

相关标签:
4条回答
  • 2020-12-15 00:47

    I know I am late. Posting for future users. Try this:

    DocumentReference datab = db.collection("Company").document("Nova");
    
    
                        datab.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
                            @Override
                            public void onSuccess(DocumentSnapshot documentSnapshot) {
    
                                if(documentSnapshot.contains("name"))
                                {
                                    Toast.makeText(YourActivity.this, "Child exixts.", Toast.LENGTH_SHORT).show();
    
                                }
                                else
                                    Toast.makeText(YourActivity.this, "Doesnt exits.", Toast.LENGTH_SHORT).show();
    
    
                            }
                        });
    
    0 讨论(0)
  • 2020-12-15 00:52

    I have solved this issue with the follwoing code, thanks for helping me!

    IN THE FOLLOWING CODE I USED TO FIND

    1)A DOCUMENT IS EXISTING OR NOT?

    2)A KEY IS EXISTING OR NOT?

    3)A VALUE IS EXISTING OR NOT?

    SIMPLE METHOD
    //////////////////////////////////////////////////////////////////////
    
    
    import 'package:flutter/material.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'dart:async';
    
    String myText1 = 'temp1';
    String myText2 = 'temp2';
    String myText3 = 'temp3';
    String myText4 = 'temp4';
    String myText5 = 'temp5';
    String myText6 = 'temp6';
    StreamSubscription<DocumentSnapshot> subscription;
    final DocumentReference documentReference =
        Firestore.instance.document("company/Nova");
    
    class Clean extends StatefulWidget {
      @override
      _CleanState createState() => _CleanState();
    }
    
    class _CleanState extends State<Clean> {
      @override
      void initState() {
        super.initState();
        subscription = documentReference.snapshots().listen((datasnapshot) {
          //FINDING A SPECIFICDOCUMENT IS EXISTING INSIDE A COLLECTION
    
          if (datasnapshot.exists) {
            setState(() {
              myText1 = "Document exist";
            });
          } else if (!datasnapshot.exists) {
            setState(() {
              myText2 = "Document not exist";
            });
          }
    
          //FINDING A SPECIFIC KEY IS EXISTING INSIDE A DOCUMENT
    
          if (datasnapshot.data.containsKey("name")) {
            setState(() {
              myText3 = "key exists";
            });
          } else if (!datasnapshot.data.containsKey("name")) {
            setState(() {
              myText4 = "key not exists";
            });
          }
    
    
          //FINDING A SPECIFIC VALUE IS EXISTING INSIDE A DOCUMENT
    
          if (datasnapshot.data.containsValue("nova")) {
            setState(() {
              myText5 = "value exists";
            });
          } else if (!datasnapshot.data.containsValue("nova")) {
            setState(() {
              myText6 = "value not exists";
            });
          }
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            new Text(myText1),
            new Text(myText2),
            new Text(myText3),
            new Text(myText4),
            new Text(myText5),
            new Text(myText6),
          ],
        );
      }
    }
    

    MY OLD COMPLEX METHOD BASED ON MY EXISTING CODE ////////////////////////////////////////////////////////

    Concept

    it has a search bar,when you type it will show the company name ie existing or not in

    A Card and a RaisedButton. I am using lower case in Firestore in order to avoid the search error. I have forced the TextFormField output to be lower case with toLowercase(). You can change it to your own text format.

    Code

    //if the name is not existing it will show a raised button so u can clcik on that to 
    //go to a COMPANY ADDING PAGE,otherwise it will only show a **CARD** so that you  
    //can't go to the next page to add your company
    
    
    //code:
    
    import 'package:flutter/material.dart';
    import 'package:cloud_firestore/cloud_firestore.dart';
    import 'dart:async';
    import './fullscreen.dart';
    
    const blue = 0xFF3b78e7;
    String filter = '';
    StreamSubscription<DocumentSnapshot> subscription;
    
    final TextEditingController _usercontroller = new TextEditingController();
    
    class CheckAvail extends StatefulWidget {
      @override
      HomeState createState() => HomeState();
    }
    
    class HomeState extends State<CheckAvail> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          resizeToAvoidBottomPadding: false,
          body: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
    // CHILD1
              new Flexible(
                child: StreamBuilder(
                  stream: Firestore.instance
                      .collection('company')
                      .where('name', isGreaterThanOrEqualTo: filter.toLowerCase())
                      .limit(1)
                      .snapshots(),
                  builder: (BuildContext context,
                      AsyncSnapshot<QuerySnapshot> snapshot) {
                    if (!snapshot.hasData) {
                      return new Column(
                        children: <Widget>[
                          new Card(
                            elevation: 5.0,
                            child: new Image.asset('assets/progress.gif'),
                          )
                        ],
                      );
                    } else {
                      return FirestoreListView1(documents: snapshot.data.documents);
                    }
                  },
                ),
              ),
    
              new Card(
                elevation: 0.0,
                color: Colors.white,
                shape: new RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(60.0)),
                child: Container(
                  padding: new EdgeInsets.only(left: 8.0),
                  child: new TextField(
                    controller: _usercontroller,
                    onChanged: (String z) {
                      setState(() {
                        filter = z;
                      });
                    },
                    decoration: const InputDecoration(
                      hintText: "Search...",
                      hintStyle: TextStyle(
                          fontFamily: 'roboto',
                          color: Colors.black38,
                          fontSize: 16.0,
                          letterSpacing: -0.500),
                      fillColor: Colors.white,
                      border: InputBorder.none,
                    ),
                  ),
                ),
              ),
            ],
          ),
          backgroundColor: Color(blue),
        );
      }
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    class FirestoreListView1 extends StatelessWidget {
      final List<DocumentSnapshot> documents;
      FirestoreListView1({this.documents});
      @override
      Widget build(BuildContext context1) {
        return ListView.builder(
            itemCount: documents.length,
            padding: new EdgeInsets.all(1.0),
            itemBuilder: (BuildContext context1, int index) {
              String name = documents[index].data['name'];
              if (name.contains(filter.toLowerCase()) &&
                  name.length == filter.length) {
                return new Container(
                  padding: new EdgeInsets.only(top: 45.0),
                  child: new Card(
                      child: new Text(
                          "Error:Already a Company Exists with this name\nTry another name")),
                );
              } else {
                return (filter.length >= 1)
                    ? new Container(
                        padding: new EdgeInsets.only(top: 15.0),
                        child: new RaisedButton(
                          onPressed: () => Navigator.push(
                              context1,
                              new MaterialPageRoute(
                                  builder: (context1) => new NextPage(
                                        value1: name,
                                      ))),
                          disabledColor: Colors.white,
                          child: new Text(
                            "Good!You can use this company name",
                          ),
                        ),
                      )
                    : new Container(padding: new EdgeInsets.only(top: 250.0),
                    child: new Card(child: new Text("CHECK IF YOUR COMPANY NAME \n           AVAILABLE OR NOT",style: new TextStyle(fontSize: 20.0),)),
                  );
              }
            });
      }
    }
    
    0 讨论(0)
  • 2020-12-15 01:07
    final QuerySnapshot result =
        await Firestore.instance.collection('users').where('nickname', isEqualTo: 
        nickname).getDocuments();
    
    final List < DocumentSnapshot > documents = result.documents;
    
    if (documents.length > 0) { 
    
      //exists
    
    } else {  
    
      //not exists
    
    }
    
    0 讨论(0)
  • 2020-12-15 01:08

    You can simply use a where query to only receive documents that have that name and then check whether you get documents. Here is an async example method that would perform what you want to know.

    Example method

    Future<bool> doesNameAlreadyExist(String name) async {
      final QuerySnapshot result = await Firestore.instance
        .collection('company')
        .where('name', isEqualTo: name)
        .limit(1)
        .getDocuments();
      final List<DocumentSnapshot> documents = result.documents;
      return documents.length == 1;
    }
    

    As you can see, I am only receiving documents, where the name field matches the given name. I also add limit(1) to make sure that I do not unnecessarily retrieve more than 1 document (which would never happen in theory) and then I just check if the length of all documents in the company collection is equal to 1 or not. If it is equal to 1, there already is a company that has that name and otherwise not.

    You could also remove the limit(1) and make the check documents.length > 1 and that would work too, but might retrieve unnecessary documents.

    Example implementation

    @override
    Widget build(BuildContext context) {
      return FutureBuilder(
        future: doesNameAlreadyExist('nova'),
        builder: (context, AsyncSnapshot<bool> result) {
          if (!result.hasData)
            return Container(); // future still needs to be finished (loading)
          if (result.data) // result.data is the returned bool from doesNameAlreadyExists
            return Text('A company called "Nova" already exists.');
          else
            return Text('No company called "Nova" exists yet.');
        },
      );
    }
    

    Here, I am not displaying an error message, which would be easily possible with the example method as well. However, the build method of some widget is used. This would e.g. work in a dialog, but I decided to do it to keep it simple and understandable. The FutureBuilder takes in doesNameAlreadyExist, in this case with the name "Nova" from your question and will, in the end, return a Text widget stating whether the name already exists.

    Be careful

    The where query is case-sensitive. This means that the check would not work if you typed e.g. "noVa" instead of "nova". As this might be important to you, you can make use of this nice method, where you would create an extra field that is insensitive, e.g. all letters are small and then you would simple query like this:

    .where('name_insensitive', isEqualTo: name.toLowerCase())
    
    0 讨论(0)
提交回复
热议问题