fetch data from firebase and query based upon users preferences
I am trying to fetch data from firebase and based upon what the user has set for their preferences, have that data present itself on a viewController. How I am fetching the data is,
func fetchPost() {
topCardView = nil
var previousCardView: CardView?
Database.database().reference().child("Post").observe(.childAdded, with: { (snapshot) in
if let userDictionary = snapshot.value as? [String: AnyObject] {
let poster = Poster(dictionary: userDictionary as [String : AnyObject])
let cardView = self.setupCardFromUser(poster: poster)
self.cardViewModels.append(poster.toCardViewModel())
if let currentUser = Auth.auth().currentUser?.uid,
currentUser == poster.fromId {
cardView.removeFromSuperview()
} else if self.topCardView == nil {
self.topCardView = cardView
}
previousCardView?.nextCardView = cardView
previousCardView = cardView
}
}, withCancel: nil)
}
the code above, shows the data that's being fetched and stored on the users VC. how I am setting the users preferences is as,
func saveSelectedToFirebase() {
print("Saving our settings data into Firestore")
guard let uid = Auth.auth().currentUser?.uid else { return }
let requiredText = selectedItems.joined(separator: ", ")
let selectedData: [String: Any] = [
"uid": uid,
"skills": requiredText
]
self.updateSelectedIntoDatabseWithUID(uid: uid, values: selectedData as [String : AnyObject])
print("Finished saving user info")
self.dismiss(animated: true, completion: {
print("Dismissal complete")
})
}
the selected items are an array of strings. If the users selectedItems match the post category, Then I would like to post to be present on the users vc. Same with cost, if the users price matches the post cost, I would like it to be present. Only in this order. If the users selected items doesn't match the post categories, there's no reason to have it present.
Just for an addition, this is how I am allowing users to make a post.
@objc func handlePost() {
guard let uid = Auth.auth().currentUser?.uid else { return }
Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String : Any] else { return }
let user = User(dictionary: dictionary as [String : AnyObject])
let docData: [String: Any] = [
"category": category,
"price": cost,
]
self.postJobDataIntoDatabseWithUID(uid: uid, values: docData as [String : AnyObject])
print("Finished saving user info")
self.dismiss(animated: true, completion: {
print("Dismissal complete")
})
}
})
}
private func postJobDataIntoDatabseWithUID(uid: String, values: [String: AnyObject]) {
let ref = Database.database().reference()
let usersReference = ref.child("jobPost").child(uid)
usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in
}
My question, is in order for me to query these items, should I fetch the users preferences first, and then fetch the post that matches? or do I have to fetch the post then tries to manipulate the items to match the user's preferences.
See also questions close to this topic
-
CALayer: create broken ellipse with round edges?
Here is my code to add an elliptic
CALayer
to aUIView
:let circleLayer = CAShapeLayer() circleLayer.path = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2, y: frame.size.height / 2), radius: frame.size.width / 2, startAngle: -.pi / 2, endAngle: .pi / 6, clockwise: false).cgPath circleLayer.lineWidth = 8.0 circleLayer.cornerRadius = 4.0 circleLayer.strokeColor = UIColor.black.cgColor circleLayer.fillColor = UIColor.clear.cgColor circleLayer.lineJoin = .round squareView.layer.backgroundColor = UIColor.clear.cgColor squareView.layer.addSublayer(circleLayer)
The result I get :
However, I would like to get this result instead:
Could you help me getting this?
Thank you for your help!
-
Simulator not showing in Spotlight search - Big Sur
Hopefully a straight forward one here, but my Simulator app (Xcode IOS Simulator) is not being found through Spotlight search on Mac. I recently upgraded to Big Sur and I am currently using 11.1.
Just wondering if anyone is having the same problem. I am able to access Simulator through other methods but it just doesn't seem to be indexed in the Spotlight search. Cheers
-
Flutter app is quitting on physical iOS device
Recently upgraded to flutter version 1.22.5 & testing my flutter app on my IOS device (14.3).
The app launched perfectly on the IOS simulator but not on my physical device.
Whenever im launching the app I get :
Error connecting to the service protocol: failed to connect to http://127.0.0.1:59046/wJX8XWG3jDg=/
I implemented :
The solution of unchecking "Disable unless needed" in the System Preferences as suggested by https://github.com/flutter/flutter/issues/46705#issuecomment-566813481
I tried to disable my firewall & to restart my device
I tried to unplug-plug my device cable again and to turn on-off the wifi (its private) as suggested by some
I deleted derived data from Xcode and cleaned the build folder
None of these solutions worked.
This is my flutter doctor -v response:
[✓] Flutter (Channel stable, 1.22.5, on Mac OS X 10.15.6 19G2021 darwin-x64, locale en-LB) • Flutter version 1.22.5 at /Users/mac/FlutterSDK/flutter • Framework revision 7891006299 (6 weeks ago), 2020-12-10 11:54:40 -0800 • Engine revision ae90085a84 • Dart version 2.10.4 [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2) • Android SDK at /Users/mac/Library/Android/sdk • Platform android-30, build-tools 30.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 12.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.1, Build version 12A7403 • CocoaPods version 1.10.0 [✓] Android Studio (version 4.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin installed • Dart plugin version 201.9317 • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) [!] VS Code (version 1.51.1) • VS Code at /Applications/Visual Studio Code.app/Contents ✗ Flutter extension not installed; install from https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [✓] Connected device (2 available) • iPhone (mobile) • 6c0132c487f1e05eadb519904911b8033debc9ba • ios • iOS 14.3 • iPhone 11 Pro Max (mobile) • B01DE645-7151-49F5-A445-21A9C0073E9D • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-1 (simulator) ! Doctor found issues in 1 category.
and this what
flutter run --verbose
ends with:[ ] Starting debug of 6c0132c487f1e05eadb519904911b8033debc9ba (D221AP, iPhone X, iphoneos, arm64) a.k.a. 'iPhone' connected through USB... [ +163 ms] [ 0%] Looking up developer disk image [ +13 ms] [ 95%] Developer disk image mounted successfully [ +985 ms] [100%] Connecting to remote debug server [ ] ------------------------- [ +615 ms] (lldb) command source -s 0 '/tmp/F0A6301B-AE37-40D0-9169-6B4B25988D2C/fruitstrap-lldb-prep-cmds-6c0132c487f1e05eadb519904911b8033debc9ba' [ ] Executing commands in '/tmp/F0A6301B-AE37-40D0-9169-6B4B25988D2C/fruitstrap-lldb-prep-cmds-6c0132c487f1e05eadb519904911b8033debc9ba'. [ ] (lldb) platform select remote-ios --sysroot '/Users/mac/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66)/Symbols' [ ] Platform: remote-ios [ ] Connected: no [ ] SDK Path: "/Users/mac/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66)/Symbols" [ ] (lldb) target create "/Users/mac/Desktop/AuxiPI/PI_Flutter_App/build/ios/iphoneos/Runner.app" [+2077 ms] Current executable set to '/Users/mac/Desktop/AuxiPI/PI_Flutter_App/build/ios/iphoneos/Runner.app' (arm64). [ ] (lldb) script fruitstrap_device_app="/private/var/containers/Bundle/Application/41BF75B2-FAB0-472E-B50A-B7AC6A77493A/Runner.app" [ +9 ms] (lldb) script fruitstrap_connect_url="connect://127.0.0.1:49950" [ +3 ms] (lldb) script fruitstrap_output_path="" [ +1 ms] (lldb) script fruitstrap_error_path="" [ +3 ms] (lldb) target modules search-paths add /usr "/Users/mac/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66)/Symbols/usr" /System "/Users/mac/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66)/Symbols/System" "/private/var/containers/Bundle/Application/41BF75B2-FAB0-472E-B50A-B7AC6A77493A" "/Users/mac/Desktop/AuxiPI/PI_Flutter_App/build/ios/iphoneos" "/var/containers/Bundle/Application/41BF75B2-FAB0-472E-B50A-B7AC6A77493A" "/Users/mac/Desktop/AuxiPI/PI_Flutter_App/build/ios/iphoneos" /Developer "/Users/mac/Library/Developer/Xcode/iOS DeviceSupport/14.3 (18C66)/Symbols/Developer" [ +79 ms] (lldb) command script import "/tmp/F0A6301B-AE37-40D0-9169-6B4B25988D2C/fruitstrap_6c0132c487f1e05eadb519904911b8033debc9ba.py" [ +6 ms] (lldb) command script add -f fruitstrap_6c0132c487f1e05eadb519904911b8033debc9ba.connect_command connect [ ] (lldb) command script add -s asynchronous -f fruitstrap_6c0132c487f1e05eadb519904911b8033debc9ba.run_command run [ ] (lldb) command script add -s asynchronous -f fruitstrap_6c0132c487f1e05eadb519904911b8033debc9ba.autoexit_command autoexit [ ] (lldb) command script add -s asynchronous -f fruitstrap_6c0132c487f1e05eadb519904911b8033debc9ba.safequit_command safequit [ ] (lldb) connect [ +47 ms] (lldb) run [ +337 ms] success [ ] (lldb) safequit [ +132 ms] Process 978 detached [ +19 ms] Application launched on the device. Waiting for observatory port. [ +25 ms] Attempting to forward device port 57290 to host port 49957 [ +1 ms] executing: /Users/mac/FlutterSDK/flutter/bin/cache/artifacts/usbmuxd/iproxy 49957:57290 --udid 6c0132c487f1e05eadb519904911b8033debc9ba [+1011 ms] Forwarded port ForwardedPort HOST:49957 to DEVICE:57290 [+2224 ms] HttpException: , uri = http://localhost:49957/ws [+2012 ms] HttpException: , uri = http://localhost:49957/ws [+2006 ms] HttpException: , uri = http://localhost:49957/ws [+2014 ms] HttpException: , uri = http://localhost:49957/ws [+2008 ms] Failed to connect directly, falling back to mDNS [ +11 ms] Checking for advertised Dart observatories... [+5039 ms] Checking for available port on com.auxi.ai._dartobservatory._tcp.local [ +2 ms] Checking for authentication code for com.auxi.ai._dartobservatory._tcp.local [ +4 ms] Attempting to forward device port 55983 to host port 49989 [ ] executing: /Users/mac/FlutterSDK/flutter/bin/cache/artifacts/usbmuxd/iproxy 49989:55983 --udid 6c0132c487f1e05eadb519904911b8033debc9ba [+1005 ms] Forwarded port ForwardedPort HOST:49989 to DEVICE:55983 [ +2 ms] Installing and launching... (completed in 45.2s) [ +1 ms] Caching compiled dill [ +239 ms] Connecting to service protocol: http://127.0.0.1:49989/wJX8XWG3jDg=/ [ +1 ms] DDS is currently disabled due to https://github.com/flutter/flutter/issues/62507 [ +12 ms] Fail to connect to service protocol: http://127.0.0.1:49989/wJX8XWG3jDg=/: HttpException: , uri = http://127.0.0.1:49989/wJX8XWG3jDg=/ws [ +1 ms] Error connecting to the service protocol: failed to connect to http://127.0.0.1:49989/wJX8XWG3jDg=/ [ +4 ms] "flutter run" took 295,502ms. [ +6 ms] #0 throwToolExit (package:flutter_tools/src/base/common.dart:14:3) #1 RunCommand.runCommand (package:flutter_tools/src/commands/run.dart:607:7) <asynchronous suspension> #2 FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:977:18) #3 _rootRunUnary (dart:async/zone.dart:1198:47) #4 _CustomZone.runUnary (dart:async/zone.dart:1100:19) #5 _FutureListener.handleValue (dart:async/future_impl.dart:143:18) #6 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45) #7 Future._propagateToListeners (dart:async/future_impl.dart:725:32) #8 Future._completeWithValue (dart:async/future_impl.dart:529:5) #9 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:40:15) #10 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:311:13) #11 RunCommand.usageValues (package:flutter_tools/src/commands/run.dart) #12 _rootRunUnary (dart:async/zone.dart:1198:47) #13 _CustomZone.runUnary (dart:async/zone.dart:1100:19) #14 _FutureListener.handleValue (dart:async/future_impl.dart:143:18) #15 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45) #16 Future._propagateToListeners (dart:async/future_impl.dart:725:32) #17 Future._completeWithValue (dart:async/future_impl.dart:529:5) #18 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7) #19 _rootRun (dart:async/zone.dart:1190:13) #20 _CustomZone.run (dart:async/zone.dart:1093:19) #21 _CustomZone.runGuarded (dart:async/zone.dart:997:7) #22 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23) #23 _microtaskLoop (dart:async/schedule_microtask.dart:41:21) #24 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5) #25 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13) #26 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5) [ +306 ms] ensureAnalyticsSent: 253ms [ +2 ms] Running shutdown hooks [ +1 ms] Shutdown hook priority 4 [ +8 ms] Shutdown hooks complete [ ] exiting with code 2
-
Create location-based app without saving coordinate
I developed a location-based application that operates in the following way:
I save the location of a user by using Geofire as follows (saves lat,on coordinate in firebase database):
if (UID != null) { geoFire.setLocation( UID, new GeoLocation( Lat_Coordinate, Lon_Coordinate ), (key, error) -> { if (error != null) { } else { } } ); }
I perform Geofire query in order to find users in a specific distance decides by the users:
geoFire.getLocation( PersonID, new com.firebase.geofire.LocationCallback() { @Override public void onLocationResult(String key, GeoLocation location) { if (location != null) { float distance = CalculateDistance( Lat, Lon, location.latitude, location.longitude ); if (!PersonID.equals( UID )) { if (distance <= Radius) { distance = distance / 1000; MapPerson mapPerson = new MapPerson( PersonID, String.valueOf( Math.round( distance ) ), itemID ); personList.add( mapPerson ); Collections.sort( personList, (o1, o2) -> o2.getPersonDistance().compareTo( o1.getPersonDistance() ) ); Collections.reverse( personList ); mapPersonAdapter.notifyDataSetChanged(); rv_RecyclerView.setVisibility( View.VISIBLE ); } } } }
Which basically looks for the location of other people and calculates the distance relative to me.
Now, it all works fine and correctly.
However, I would like to save the least possible information about the users due to privacy limits.
Is there any technique to perform such calculations or recommended algorithm to find users around me in some radius without saving their location into my
firebase
database?Thank you
-
Firebase Auth - Disable a user and prevent him interacting with the backend
If a user of my app performs some unwanted action, his account may be disabled by a moderator. However, even if disabled, he will be able to use the app if he is already logged in. How can I prevent this?
The code I use to disable a user is within a Cloud Functions and use the following:
admin.auth().updateUser(uid, { disabled: true });
-
Firebase Firestore best way to secure chat messaging whilst minimising Firestore reads
So I have a collection of User profiles.
Separate from this I guess I'm having another collection storing the Users email & password, only accessible to the user.
My app's Users talk to one another through a chat screen.
I'm a cheapskate, I want minimum database accesses but need to know the consequences.
In the Users record I have a List containing IDs of folk the user is chatting with, this get hashed with the Users ID, so chat msgs can be retrieved.
This needs to be modifiable by anyone who uses the app, they need to be able to append their ID.
It appears Firestore cannot allow a User to write to a field of a record, but not see or write to other fields of that record, is this correct?
So, for security, it would appear I need a separate Chat record for each User, so anyone can write their userId to that, but they can't hack into the User's profile fields.
Is this correct? I'm so cheap I want to run away from it, more records = more database reads. 50k free accesses a day... gives me cold sweats.
-
Efficient and Scalable social presence with Firebase Realtime Database
I am currently implementing a friends list in a mobile app that I would like to add realtime presence too. I am new to firebase and trying to think of the most scalable and efficient way to accomplish this.
A given user can have up to 50 friends. I already have a user's collection that gives presence for a given user. Friends are a mutual relationship. It's a friend system, not a follow system.
I have a couple of ideas for how to accomplish this.
Solution A: Many Listeners
User A has a collection of Friends. All users have a "status" field that tracks online presence. User A would create listeners to each of their friend's documents in the "users" collection and render the info in a list.
- users - UserAGuid - location : lobby - level : 20 - status : online - FriendAGuid - location : match - level : 10 - status : online - FriendBGuid - location : lobby - level : 15 - status : offline - friends - UserAGuid - FriendAGuid : true - FriendBGuid : true - FriendAGuid - UserAGuid : true - FriendBGuid - UserAGuid : true
Concern with A: Having up to 50 listeners per client feels like a scale problem.
Solution B: Multicast Update
- users - UserAGuid - status : online - FriendAGuid - status : online - FriendBGuid - status : offline - friends - UserAGuid - FriendAGuid - location : match - level : 10 - status : online - FriendBGuid : true - location : lobby - level : 15 - status : offline - FriendAGuid - UserAGuid - location : lobby - level : 20 - status : online - FriendBGuid - UserAGuid - location : lobby - level : 20 - status : online
When any user state changes they do a multicast update to all of their entries in their friends "friends" documents. This means that a given user only needs to listen for updates to their own "friends" document.
Concern with B: From what I have read this kind of denormalization and multicast update is the preferred way to do this but know example describes a use case that will be this write heavy. In this example, every time the user comes online they are writing to 50
Question
Which solution is the correct one for an application that might have millions of DAU each with several sessions a day? Is there another solution that I have not considered?
-
Firfebase Auth across apps in the same project javascript
Does firebase auth keep you logged in across apps in the same project?
If not is there any way I can?
Thank you!
-
How to restore a Firebase Realtime Database?
I have a Realtime Database in Firebase and I want to delete almost all entries from one branch of the JSON. I prefer don't do it in a bulk way because I would lose all entries, but I didn't find another way.
I couldn't do it either in that way because of the amount of data. Firebase says that the database is shown in only read version because the data slows the web.
My last try has been to download a backup and import it again, but I have the next error:
El JSON no es válido. Las claves no pueden estar vacías ni incluir $ # [ ] / ni
This is not measured up to Google.
-
How to paginate in firebase android?
I have a timeline with "comments" and I want to load 10 comments at first and then load more 10 each time the user gets to the bottom of the recyclerview on scrolling. I'm really struggling to achieve this cause at the same time I need the recyclerview to show items from the newest to the oldest.
I know there's a lot of similar questions but I could not adapt any of them to my case.
Here's what I've tried until now:
rvComments.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (!isLoading) { if (layoutManager != null && layoutManager.findLastCompletelyVisibleItemPosition() == commentSize - 1) { loadMoreComments(); } } } });
Method to load comments:
private void loadMoreComments() { Query query = Util.mServerDatabaseRef.child(Util.getServer().getServerUID()).child("timeline").child("commentList").orderByChild("date").startAt(lastTime).limitToLast(2); new Thread(() -> query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { isLoading = true; if (!onlyRefresh) { commentList = new ArrayList<>(); for (DataSnapshot snap : dataSnapshot.getChildren()) { Comment comment = snap.getValue(Comment.class); if (comment != null) { comment.setCommentUID(snap.getKey()); commentList.add(comment); lastTime = comment.getDate(); commentSize++; } } NUMBER_OF_ADS = commentList.size(); if (!commentList.isEmpty()) { initRecyclerViewComment(onlyRefresh); } } onlyRefresh = true; isLoading = false; if (adapter != null) { adapter.notifyDataSetChanged(); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } })).start(); }
The current code works well for the first time, it really retrieves the 2 last comments but when scrolling it won't work. What should be my "startAt"? Is there a better way to do that?
Just to clarify the expected behavior is: Load x(10) more recent comments -> user scrolls to bottom -> loads next 10 more recent comments...
-
firebase-queue worker not listening for events, not retrieving existing events
I am using the same code from the firebase-queue guide
// my_queue_worker.js var Queue = require('firebase-queue'); var admin = require('firebase-admin'); var serviceAccount = require('path/to/serviceAccountCredentials.json'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: '<your-database-url>' }); var ref = admin.database().ref('queue'); var queue = new Queue(ref, function(data, progress, resolve, reject) { // Read and process task data console.log(data); // Do some work progress(50); // Finish the task asynchronously setTimeout(function() { resolve(); }, 1000); });
And I have a separate process which is successfully putting events into the queue:
Here are the rules for the database, "collection" and "data" are properties in the queue database table:
{ "rules": { "queue": { "tasks": { ".read": true, ".write": true, ".indexOn": "_state", "$taskId": { ".validate": "newData.hasChildren(['collection', 'data'])", "_state": { ".validate": "newData.isString()" }, "_state_changed": { ".validate": "newData.isNumber() && (newData.val() === now || data.val() === newData.val())" }, "_owner": { ".validate": "newData.isString()" }, "_progress": { ".validate": "newData.isNumber() && newData.val() >= 0 && newData.val() <= 100" }, "_error_details": { "error": { ".validate": "newData.isString()" }, "error_stack": { ".validate": "newData.isString()" }, "previous_state": { ".validate": "newData.isString()" }, "original_task": { /* This space intentionally left blank, for malformed tasks */ }, "attempts": { ".validate": "newData.isNumber() && newData.val() > 0" }, "$other": { ".validate": false } }, "_id": { ".validate": "newData.isString()" }, "collection": { ".validate": false }, "data": { ".validate": false } } }, "specs" : { ".read": true, ".write": true, "$specId": { ".validate": "newData.hasChild('in_progress_state')", "start_state": { ".validate": "newData.isString()" }, "in_progress_state": { ".validate": "newData.isString()" }, "finished_state": { ".validate": "newData.isString()" }, "error_state": { ".validate": "newData.isString()" }, "timeout": { ".validate": "newData.isNumber() && newData.val() > 0" }, "retries": { ".validate": "newData.isNumber() && newData.val() >= 0" }, "$other": { ".validate": false } } } } } }
And what I would expect happen is:
1) When the firebase-queue worker starts, it checks the existing queue entries and starts working.
2) When new queue entries are created it processes them.But neither of those 2 things are happening. Any suggestions?