I'm really new to flutter and coding. I'm working on an application just like Instagram but only shows users that check in to the same location. What I am trying to achieve, is that after the user has checked in, I want to display all the users that checked in within that day. However, I am not sure about the database structure, or how to write it at all. If there is any advice on any step, I am more than happy and grateful for all the comments.
Here is what my database structure looks like.
[Database Structure][1]
I am planning to use RxDart to combine streams so that the story can be updated as a new user check-in or post a story. Here is what my application currently looks like. (Please correct me at any point if I can achieve the result by a more efficient method)
[UI of the feed][2]
I understand that my code probably is completely wrong but it is the best effort from me. Please understand.
Approach 1: I tried to follow [this][3] document but am struggling to implement it.
class CheckinsListViewModel {
CheckinsListViewModel({required this.database});
final FirestoreDatabase database;
#override
Stream<List<UserCheckins>> UserTest() {
return Rx.combineLatest2(database.userStream(), database.checkinStream(),
(List<model.User> users, List<Checkins> checkins) {
return users.map((user) {
final checkin = checkins.firstWhere(
(checkin) => checkin.uid == user.uid,
);
return UserCheckins(users: user, restaurants: checkin.rid.toString());
}).toList();
});
}
}
Approach 2
I am not sure if I can achieve something like this because approach 1 is overwhelming for me. If anyone can clarify, it'd make my day.
class CheckinsListViewModel {
CheckinsListViewModel({required this.database});
final FirestoreDatabase database;
#override
Stream<List<UserCheckins>> UserTest() {
return Rx.combineLatest2(
FirebaseFirestore.instance.collection('users').snapshots(),
FirebaseFirestore.instance.collection('checkins').snapshots(),
(AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> users,
AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> checkins) {
return //somehow map and return uid from each documents;
}).toList();
}
}
I am new to StackOverflow. If there is more information needed (which I believe so) please feel free to guide me. Thank you for all your responses, whether they be a criticism or a solution.
[1]: https://i.stack.imgur.com/uT06e.png
[2]: https://i.stack.imgur.com/o5542.png
[3]: https://codewithandrea.com/videos/rx-dart-by-example-combine-latest/
Related
I have a set of APIs that's available under /api/v1/ route, and a set of internal APIs (stuff that makes the admin panel tick and such) under /admin/api/v1/ route. I currently have NSwag with OpenAPI documents and SwaggerUI3 implemented, but it contains all routes.
After a couple of hours of googling, cursing, and I'm pretty sure getting a mild aneurysm, I managed to scavenge what precious few bits and pieces of information exist and cobble together this bit of code:
// OpenAPI
app.UseOpenApi();
app.UseSwaggerUi3(settings =>
{
settings.Path = "/swagger";
});
// OpenAPI Internal
app.UseOpenApi(settings =>
{
settings.Path = settings.Path.Replace("swagger", "swagger-internal");
});
app.UseSwaggerUi3(settings =>
{
settings.Path = "/swagger-internal";
settings.DocumentPath = settings.DocumentPath.Replace("swagger", "swagger-internal");
});
which does provide me with two separate documents, and two separate UIs. However, despite their differing routes, they share the functionality, fully.
I found this issue that barely has enough information to direct me to a deleted file from the repo and this documentation that's of minuscule if any help at all.
I know that I can write some filter or something (how, though, that's anybody's guess) and use this bit of code:
services.AddOpenApiDocument(settings =>
{
// the settings here in particular
});
and perhaps, yet again, duplicate it or something. But this is where I'm absolutely and utterly stuck and I have no idea how to progress further. I only know that all those bits and pieces of code are glued together with magic strings, but where to apply the glue in this case, that I do not know.
I heard rumors and legends that someone somewhen knew a distant relative of somebody who managed to do that, so perhaps I'll be lucky and this person is here.
Update 1:
I did manage to hack together this bit
public class IncludeInternalApisProcessor : IOperationProcessor
{
public bool Process(OperationProcessorContext context)
{
return context.ControllerType.FullName?.ToUpper().Contains("ADMIN") ?? false;
}
}
and
services.AddOpenApiDocument(settings =>
{
settings.SchemaNameGenerator = new NSwagNestedNameGenerator();
});
services.AddOpenApiDocument(settings =>
{
settings.DocumentName = "internal";
settings.OperationProcessors.Add(new IncludeInternalApisProcessor());
settings.SchemaNameGenerator = new NSwagNestedNameGenerator();
});
but now I feel filthy having done that. And I lose out on versioning.
How to display the data submitted by the current user on a widget?
I already tried with streamBuilder and FutureBuilder and nada.
Firebase Users data
Screen where the current user data should be displayed
I could manage to displayed the data (country, username, email, password) from the first Firebase document by using: docs[0]['country'] but that's not right... It needs to be displaying the data from the current user and not always the data from the first document.
I already tried ListView.builder(), but when you scroll down you'll see all data as a list from all users and that's wrong too.
I look forward to seeing your answers.
Thanks in advance for the help guys.
As i understand you want to take data about current or any user. First of all detect userId and you can work this code(I wrote very simple code for my project and you can apply to your code.)
This is Model Class
class MyUser{
String snapshotId;
String userId;
String name;
MyUser({this.userId,this.snapshotId,this.name});
factory MyUser.fromSnaphot(DocumentSnapshot snapshot){
return MyUser(
snapshotId:snapshot.id,
userId:snapshot.data()['userId'],
name:snapshot.data()['name'],
);
}
This is Service Class
final FirebaseFirestore _fBaseFireStore=FirebaseFirestore.instance;
CollectionReference _collectionRef;
UserService(){
_collectionRef=_fBaseFireStore.collection('Users');
}
Stream<MyUser> getUserFromUserId(String userId){
var ref=_collectionRef.where('userId',isEqualTo:userId);
return ref.snapshots().map((event) => MyUser.fromSnaphot(event.docs[0]));
}
Get User Function
final UserService _userService = getIt<UserService>();
return _userService.getUserFromUserId(userId);
I'm working on a project, where we need to make non optional connections, and I can't really find anything on the subject.
I made the fields work with the NonNullableGraphType as shown beneath, but I have no luck getting the connections to be non nullable.
I've searched far and wide, and can't find anything about the issue, so I hope someone can help me here, as I'm completely lost.
The fields that are non nullable are written as such:
Field<NonNullGraphType<OrderPresetGraphType>>(
"preset",
resolve: context => {
var loader = dataLoader.Context.GetOrAddBatchLoader<int, Base.Entities.Orders.OrderPreset>(
"OrderPresetById", orderPresetController.GetOrderPresetsByIdAsync
);
return loader.LoadAsync(context.Source.PresetId);
}
);
Sadly, the same method doesn't work with lists.
Any help is much appreciated!
Edit
My current attempt at solving this, looks like this:
Connection<NonNullGraphType<AssetFilterPresetFieldGraphType>>()
.Name("fields")
.Unidirectional()
.Description("Returns a list of AssetFilterPresetFieldGraphType connected to this AsetFilterPresetGraphType")
.ResolveAsync(async context =>
{
var result = await assetFilterPresetController.GetFilterPresetFieldsByIdAsync(context.Source.Id)
.ConfigureAwait(false);
return ConnectionResolver.ToConnection(result.Data, context);
});
I stumbled into this problem as well. I solved by wrapping the current type with NonNullableGraphType using an extension method.
public static ConnectionBuilder<TSource> NonNullable<TSource>(
this ConnectionBuilder<TSource> builder
)
{
builder.FieldType.Type = typeof(NonNullGraphType<>).MakeGenericType(builder.FieldType.Type);
return builder;
}
Use it like this:
Connection<UserGraphType>()
.Name("users")
.NonNullable()
.Resolve(ctx => /*...*/);
i have a function that creates and add new data to the cloud firestore! i want the function to check if the documents already exist, if so update them otherwise create them!
i do not know how its done. can someone help me with this please!
thank you all in advance.
this is the function.
static void createPostMonday(Post post) {
postsRef.document(post.authorId).collection('Monday').add({
'alOne':post.alOne,
'altwo':post.alTwo,
'althree':post.alThree,
'alFour':post.alFour,
'alFive':post.alFive,
'alSix':post.alSix,
'beOne':post.beOne,
'beTwo':post.beTwo,
'beThree':post.beThree,
'beFour':post.beFour,
'beFive':post.beFive,
'beSix':post.beSix,
'likes': post.likes,
'authorId': post.authorId,
'timestamp': post.timestamp,
});
}
I'm wondering if this is possible, and if it's a good solution to my problem.
I want users to be able to subscribe to content. The content is associated with an id.. for instance:
'JavaScript': 1,
'C++': 2,
'Python': 3,
'Java': 4,
Let's say a user subscribes to 1, 3, and 4.
So their user json data would appear as:
'subscribed_to': [1,3,4]
Now in my firestore, I have posts. Each post gets assigned a content_id (1-4 for instance), and so when I query for the content that this user is subscribed to, how would I do that so as effectively as possible?
This is indeed a complex but common case, I would recommend to set a data structure similar to:
{
"subscriptions" {
javascript: { ... },
python: { ... },
java: { ... }
},
"users": {
1: {
subscribed_to: ['javascript', 'python']
}
}
}
It's very important that on your subscribed_to prop you use the doc name, cause this is the part that allows you to query them (the docs).
the big problem, how do I query this data? I don't have joins!
Case 1:
Assuming you have your user data when you apply load...
const fetchDocs = async (collection, docs) => {
const fetchs = docs.map(id => collection.doc(id).get())
const responses = await Promise.all(fetchs)
return responses.map(r => r.data())
}
const userSubscriptions = ['javascript', 'python']
const mySubscriptions = await fetchDocs(`subscriptions`, userSubscriptions)
Behind the scene, the sdk will group all the queries and do its best efforts to deliver em together. This works good, I'm 99% sure you still have to pay for each query individually each time the user logs in.
Case 2:
Create a view dashboard collection and pre-calculate the dashboard behind the scene, this approach involves cloud functions to listen or changes on the user changes (and maybe subscriptions as well) and copy each individual doc into another collection, let's say subscriptions_per_users. This is a more complex approach, I will require more time to explain but if you have a big application where costs are important and if the user is going to subscribe to a lot of things, then you might want to investigate about it.
Source: My own experience... a little of google can also help, there seems to be a lot of opinions about it, find what works best for you.