Flutter: multiple firebase projects in one app but showing incorrect data

Viewed 2446

The last few days I spend a lot of time to read through several SO-questions and tutorials. What I'm trying to achieve is, that a user of my flutter app can choose a firebase project and log in with email/password. After the login, obviously, the correct data of the corresponding database should be shown. And that is where I fail.

After a while of reading some sites and questions from SO, I went with the following site to get the first part of the login.

https://firebase.googleblog.com/2016/12/working-with-multiple-firebase-projects-in-an-android-app.html

After working through this article, I was able to successfully log in to my defined firebase projects.

How did I know that the login was successful? I compared the user-uids from the projects with the print statement from my app in the console. That was the prove my configuration for the non-default project is correct.

But now the main problem which I can't solve. After the login, the data is always of the default firebase project from the google-service.json.

For state management, I choose the provider package, as they mentioned in the I/O '19. So inside my main.dart, I wrap the whole application with MultipleProvider:

Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<LoginModel>(
          builder: (_) => LoginModel(),
        ),
        ChangeNotifierProvider<Auth>(
          builder: (_) => Auth(),
        ),
      ],
      child: MaterialApp(
        title: 'Breaking News Tool',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: RootPage(),
      ),
    );
  }

The provided Auth class is a service that connects to firebase sdk and also configure non-default apps to create the needed firebase auth

abstract class BaseAuth {

  getDefaultAuth();

  getAbnAuth();
...
}

class Auth with ChangeNotifier implements BaseAuth {
 ...
  Auth() {
    _configureAbnApp();
    _configureProdApp();
  }

  getDefaultAuth() {
    _firebaseAuth = FirebaseAuth.instance;
  }

  getAbnAuth() {
    _firebaseAuth = FirebaseAuth.fromApp(_abnApp);
  }

  _configureAbnApp() {
    FirebaseOptions abnOptions = FirebaseOptions(
        databaseURL: 'https://[project-id].firebaseio.com',
        apiKey: 'AIzaSxxxxxxxxxxxxxxxx,
        googleAppID: '1:10591xxxxxxxxxxxxxxxxxxx');
    FirebaseApp.configure(name: 'abn_database', options: abnOptions)
        .then((result) {
      _abnApp = result;
    });
  }
...
}

After a log in the app redirects the user to the home_page (StatefulWidget). Here I use a snapshot of the database to show data.

_stream = Firestore.instance.collection(collection).snapshots();
...
Center(
        child: Container(
          padding: const EdgeInsets.all(10.0),
          child: StreamBuilder<QuerySnapshot>(
            stream: _stream,
            builder:
                (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (snapshot.hasError)
                return Text('Error: ${snapshot.error}');
              switch (snapshot.connectionState) {
                case ConnectionState.waiting:
                  return Text('Loading...');
                default:
                  return ListView(
                    children: snapshot.data.documents
                        .map((DocumentSnapshot document) {
                      return CustomCard(
                        docID: document.documentID,
                        title: document[title],
                        message: document[message],
                        fromDate: document[fromDate],
                        endDate: document[endDate],
                        disableApp: document[disableApp],
                      );
                    }).toList(),
                  );
              }
            },
          ),
        ),
      ),

In the beginning, I only had one project to connect to and the data was correct. But now I successfully connect to another project with the correct user-uid, but the data is always from the default project which is defined by the google-service.json. And at this point, I have no clue why this happens.

Did anyone have an advice or idea?

1 Answers

You create your _stream based on Firestore.instance, which will give you the default firebase app, as documented in the docs:

/// Gets the instance of Firestore for the default Firebase app.
static Firestore get instance => Firestore();

Therefore you always get the data from the default project. To fix this you need to create your firestore using the app created by FirebaseApp.configure().

So replace:

_stream = Firestore.instance.collection(collection).snapshots();

with

_stream = Firestore(app: _abnApp).collection(collection).snapshots();
Related