Wait screen until document added to Firestore subcollection? - firebase

I am make random chat app with Flutter and Firestore.
When first user want to chat, I want show wait screen (CircularProgressIndicator). When second user join chat, I want show main chat screen.
But how can I make client app listen continuous for user2 to join? Base on my Firestore schema it must listen for user2 to join /roomUsers subcollection (user2 is add as document name UID). This subcollection already have data for first user so cannot just listen if subcollection hasdata.
#jurrdb has post this code on stackoverflow:
class MyScreen extends StatefulWidget {
#override
_MyScreenState createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
Widget _screen;
#override
void initState() {
_screen = CircularProgressIndicator();
_doSomeFirebaseChecking();
}
void _doSomeFirebaseChecking() async {
// Add your code that performs checks at Firebase here.
// Then use setState to update the widget to a screen of choice.
setState(() {
});
}
}
I am try use this model but no know how to make client app check Firestore subcollection continuous.
I have try get documents from /roomUsers subcollection and check if documentSnapshot.length > 1 but this only run once so not update when user2 join chatroom.
How can solve this? I am try streambuilder/futurebuilder but no solve.
Thanks!
Update: Here how I write "user document" into the roomUsers subcollection:
roomUsersRef = Firestore.instance.collection(‘chats').document(docID).collection(‘roomUsers').document(uid);
await roomUsersRef.setData({
‘user2UID': uid,
});

Related

Firebase Document reference where value may change

I have a situation where I have a collection which contains information that displays a user profile picture, this user picture is taken from another collection's (users) document. My problem is that I add a link to the picture when I create the new document, this means that if in future the user changes the profile picture the other collection would not have that new information. Is there a way I can solve this with firebase?
I want to get the data from the other collection whenever the information in users collection is updated.
document value in the collection that needs live data
{profile-picture:"image-from-users-collection goes here"}
document value in /users collection
{user-picture:"my-pic.png"}
I want to get the data from the other collection whenever the
information in users collection is updated.
A mentioned by Mises, one standard approach is to use a Firestore Cloud Function which is triggered when the user document changes.
The following code will do the trick. I make the assumption that the document of the other collection uses the same ID than the user document.
exports.updateUserImage = functions
.firestore
.document('users/{userId}')
.onUpdate(async (change, context) => {
try {
const newValue = change.after.data();
const previousValue = change.before.data();
if (newValue['user-picture'] !== previousValue['user-picture']) {
await admin.firestore().collection('otherCollection').doc(context.params.userId).update({'profile-picture':newValue['user-picture']});
}
return null;
} catch (error) {
console.log(error);
return null;
}
});

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:
User signs up
User document created in Firestore
Firebase Function triggered to create 'other' document
User sees homepage
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
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();
}

How to copy all documents from one collection to other in Firestore -Flutter?

I am in a situation where when a users makes a payment, his cart products Stored in Firestore collection (CartProducts) should be moved to new collection Called SuccessFullOrders .
So my Basic Question is how to move all documents from one collection to Firestore other Collection in Flutter
I don't Know how to write code for this in flutter.Thanks for your Answers
Here's my Code
void _onPressed()async {
final FirebaseAuth _auth = FirebaseAuth.instance;
FirebaseUser user = await _auth.currentUser();
print(user.uid);
firestorInstance.collection("users").getDocuments().then((querySnapshot) {
querySnapshot.documents.forEach((result) {
firestorInstance.collection("users").document(user.uid).collection("CartProducts").getDocuments().then((querySnapshot) {
querySnapshot.documents.forEach((result) {
//what to write here so that new documents would be created in other collection
print(result.data);
});
});
});
});
}
Currently there's no way to copy a collection into another provided by firebase officially. And, for sure, you can iterate over your previous collection & create new documents in the other.
In your case you should be doing something like:
userFirebaseInstance
.collection(NewCollection)
.document()
.setData(YourDataHere)

How to delete a subcollection from firestore flutter

so am new using firestore to store data. at the moment i need to delete data already saved in the Firestore through my App. I have tried
Future<void> removeDocument(String id, String userId){
return ref.document(userId).collection(userId).document(id).delete().whenComplete((){
print("DELETE DONE::");
});
}
But its not working.
The thing is I used the userId to save the user details
now I want to delete the data but it does not delete the data even though the print message shows in my Log.
The method below is how i add data to the Firestore
Future<void> addDocument(Map data, String userId){
return ref.document(userId).collection(userId).add(data);
}
void setupLocatorWorkout() {
locatorWorkout.registerLazySingleton(() => Api('workout_goal'));
locatorWorkout.registerLazySingleton(() => CRUDRemoteDataSource());
}
Api(this.path){
print("$path");
ref = _db.collection(path); // this is the base collection
}
please what am i doing wrong here?
Thank you!!!
Delete a User by UID:
void deleteUser(User user) async {
await db.collection(COLLECTION_NAME)
.document(user.uid)
.delete()
.then((_) {
print('User deleted.');
});
}
Don't forget to add import 'dart:async'; at the top
The answer is you shouldn't.
According to the Firestore docs, you should not do this because:
While it is possible to delete a collection from a mobile/web client, doing so has negative security and performance implications.
However the link shows how it can be done frome some platforms.

How to create a custom document in collection - Firestore with Flutter

I sign in my user through google, after successfully login. I wants to create document for each user inside user_details collection and the document name should be google id. But its auto generating document name.
Is there any way to create custom document in Firestore?
Thanks in Advance
// Store data in Firestore
storeData(User user) async {
DocumentReference documentRef =
Firestore.instance.collection("user_details").document(user.id);
Firestore.instance.runTransaction((transaction) async {
await transaction.set(documentRef, user.toJson());
print("instance created");
_login.add(Result(Status.SUCCESS, "Login successful.", user));
});
}
Try this await documentRef.setData(user.toJson());

Resources