How to Display a Loading Spinner While Getting Data from Firestore

How to display a loading spinner while getting data from firestore

I suggest creating a controller for circularProgress, as in the example:

class _testProgressState extends State<testProgress> {

bool _progressController = true;


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

subscription = collectionReference.snapshots().listen((datasnapshot) {
setState(() {
snapshot = datasnapshot.documents;
_progressController = false;
});
});

}

@override
Widget build(BuildContext context) {
return Scaffold(
body: _progressController
? CircularProgressIndicator()
: ListView.builder(
itemCount: 3,
itemBuilder: (context, index) {
return Card();
}),
);
}
}

So whenever you find it necessary to call some function to collect data, just setState setting _controllerProgress to true, and when the data arrives returns it to false!

Trying to implement loading spinner while loading data from Firestore with Flutter

The other answers look reasonable. They are just missing data validation checks, which I find is required in all my apps. Because if I have a good connection, and hasData is true and hasError is false, there might be no documents at all though. This should be checked. Here is a snippet from my projects.

Checking connection state is the same as just checking snapshot.hasError.

Widget _getMyFriends() {
return StreamBuilder<QuerySnapshot>(
stream: Database.getFriendsByUserId(widget.loggedInUserId),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return Center(child: Text("Error"));
else if (!snapshot.hasData)
return Center(child: Text("Loading..."));
else if (snapshot.data.documents.isEmpty) //also check if empty! show loader?
return Center(child: Text("No friends added yet."));
else
return ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return SimpleUserPanel(userId: document['friendid']);
}).toList(),
);
}
);

}

how to display spinner when data is being fetched from cloud firestore in vuejs?

I would tweak your v-if/v-else logic at bit.

<loadingSpinner v-if="loading" />
<div v-else-if="posts.length"></div>
<div v-else>
<p class="no-results">There are currently no posts</p>
</div>

The difference is v-else-if on posts.length, instead of v-if. This way, there are 3 distinct states.

  1. Loading, show spinner.
  2. Not loading, show posts.
  3. Not loading, there are no posts, show no results.

How to show activity indicator until all data from firestore are fetched and displayed in react native using redux

Change

if(isLoading){
return <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
<ActivityIndicator size="large" color={Colors.primary}/>
</View>
}

if(!isLoading&&products.length===0)
{
return <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
<Text>No Products</Text></View>
}

to

if(!isLoading && products.length===0){
return <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
<ActivityIndicator size="large" color={Colors.primary}/>
</View>
}

if(isLoading&&products.length===0)
{
return <View style={{flex:1,alignItems:'center',justifyContent:'center'}}>
<Text>No Products</Text></View>
}

Hope this helps!

Display a loading icon until Firebase firestore fully loads data into a textview

You can use ProgressBar and call ProgressBar.setVisibility(View.GONE) to hide the progress bar once the data is loaded.

First add a ProgressBar outside of the rest of your layout and set the visibilty of the layout you want to hide to gone

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"> // Initially hide all the body

<TextView
android:id="@+id/welcomeTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome"
app:layout_constraintBottom_toTopOf="@+id/logOutBtn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.84000003" />

<Button
android:id="@+id/logOutBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Log out"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

And once the data is loaded hide the ProgressBar and make the mainContent layout Visible

ProgressBar progressBar = findViewById(R.id.progressBar); // Get ProgressBar reference
ConstraintLayout mainContent = findViewById(R.id.mainContent);
welcomeTv = findViewById(R.id.welcomeTv);
fStore = FirebaseFirestore.getInstance();


fStore.collection("Users").document(FirebaseAuth.getInstance().getCurrentUser().getUid()).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
progressBar.setVisibility(View.GONE); // Hide Progress bar
mainContent.setVisibility(View.VISIBLE); // Show TextView

if (task.isSuccessful() && task.getResult() != null) {

username = task.getResult().getString("username");
welcomeTv.setText(username);

//other stuff
} else {
Toast.makeText(HomeActivity.this, "Currently logged in", Toast.LENGTH_SHORT).show();
}


}
});

Hope it helps

Update: Updated the code with your layout mentioned in comments.

How to show Circular progress indicator while fetching document from Firestore

Make your Widget a StatefullWidget and set a boolean value isLoading to false.
Make sure that your DatabaseService is asynchronous and await it.
If the value of isLoading is true show a CircularProgressIndicator.

Here is a basic example:

import 'package:flutter/material.dart';

class YourWidget extends StatefulWidget {
@override
_YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
bool isLoading = false;

Future getScore() async {
setState(() {
isLoading = true;
});
//////////////////////////////////////////////////////////////////////
// This is where I call the getScore function in database dart file //
//////////////////////////////////////////////////////////////////////
await DatabaseService(uid: globals.uid).getScore(
'level11',
);
/////////////////////////////////////////////////////////////////////////////////////////////////
// I would like the circular indicator until data is fetched and before the new view is pushed //
/////////////////////////////////////////////////////////////////////////////////////////////////

setState(() {
isLoading = false;
});

Navigator.push(
context, CupertinoPageRoute(builder: (context) => GameHome()));
}

@override
Widget build(BuildContext context) {
return Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
child: Column(
children: [
ElevatedButton(
onPressed: getScore,
child: Text(
'Play',
style: Theme.of(context).textTheme.headline2,
),
style: OutlinedButton.styleFrom(
shape: StadiumBorder(),
padding: EdgeInsets.symmetric(
horizontal: 5.25 * SizeConfig.textMultiplier,
vertical: 1.125 * SizeConfig.textMultiplier),
side: BorderSide(width: 1, color: Colors.black26),
backgroundColor: Colors.black,
),
),
Visibility(visible: isLoading, child: CircularProgressIndicator())
],
),
),
);
}
}


How to show a loading animation during firebase query in SwiftUI

You need to use @Published in the @ObservableObject (not @Binding).

Here is a possible demo:

class Fetch: ObservableObject {
@Published var loading = false

func longTask() {
self.loading = true
// simulates a long asynchronous task (eg. fetching data)
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.loading = false
}
}
}
struct ContentView: View {
@ObservedObject private var fetch = Fetch()

var body: some View {
ZStack {
Text("Main view")
if fetch.loading {
LoadingView() // can be replaced with any other loading indicator/view
}
}
.onAppear {
self.fetch.longTask()
}
}
}
struct LoadingView: View {
var body: some View {
ZStack {
Color.black
.opacity(0.5)
.edgesIgnoringSafeArea(.all)
Text("Loading")
}
}
}


Related Topics



Leave a reply



Submit