MrHarvey
MrHarvey

Reputation: 282

Run Firebase Cloud Function before page load Flutter

I have a Firebase Cloud Function that creates a document when a new user signs up. The document that gets created by the function is where the user data will be stored. The process is as such:

  1. User signs up
  2. User document created in Firestore
  3. Firebase Function triggered to create 'other' document
  4. User sees homepage
  5. Homepage uses data from 'other' document

The problem I have is the user is going straight to the homepage before the Firebase Function is executed and the 'other' document is not created yet.

This means the user is just seeing a CircularProgressIndicator because the page is loading before the 'other' document exists.

It works fine if the user clicks away from that page and returns to it, because by that time the 'other' document exists. Likewise, when I add a 5 second delay on initially loading the homepage, it works because the Firebase Function has time to execute - but this is not a nice solution.

I am wondering how I can ensure the Firebase Function has executed and the 'other' document created before loading the homepage?

initState

void initState() {
    super.initState();
    final user = Provider.of<UserClass>(
      context,
      listen: false); 
    final uid = user.uid;
    _houseID = getHouseID(uid);
  }

Future returning ID of document created by Firebase Function

  Future<String> getHouseID(uid) async {
    String houseID;
    await Future.delayed(Duration(milliseconds: 5000)); // with this delay it works fine 
    await FirebaseFirestore.instance
        .collection('users')
        .doc(uid)
        .collection('userHouses') // this collection is being created by a Cloud Function
        .get()
        .then(
      (value) {
        houseID = value.docs.single.id;
      },
    );
    return houseID;
  }

FutureBuilder

   return FutureBuilder(
      future: _houseID,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        hhid = snapshot.data;
        if (!snapshot.hasData) {
          return Center(child: CircularProgressIndicator()); // this runs forever when the user first signs up
        } else {
          return // homepage using hhid to retrieve user data

Upvotes: 0

Views: 267

Answers (1)

osaxma
osaxma

Reputation: 3014

You can open a stream which listens to that specific document after the user signs up. The stream initially may be empty, so you can check if the document exists. Once the document is written, the stream will be updated and then you can close it if you're done.

here's a simple code that explains the idea:

final subscription = FirebaseFirestore.instance.doc('path-to-document').snapshots().listen((event) {
  if (event.exists) {
    // do something with the data
    final data = event.data();

    // update your state
    // .... some code

    // call a function to close the subscription if you don't need it
    closeSubscription();
  }
});

closeSubscription() {
  subscription.cancel();
}

Upvotes: 1

Related Questions