Can't create trigger in Realm - ios

I'm using Realm in iOS, I have user table and history table.When user table's record is updated or created,I want to create a trigger to save this event in history table.

Check out the Notifications section of Realm documentation. You should use a notification token to listen changes made to your User table and then run the code that saves the event to History table in the notificationBlock of the token.

Related

How to observe conversations in iOS app powered by Firebase Realtime Database?

=====================
I thought about it for a while and proposed a potential solution at the end of the question, do you think it's feasible?
=====================
I'm using Firebase Realtime Database to support chatting in my iOS app. I have a node called "conversations" in database, which is structured like so:
-conversations
-user_id_1 // This is you
-recipient_id_1 // id of the user who's chatting with you
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
-recipient_id_2
-message_id_1
-message: <some_message>
-date: <some_date>
-message_id_2
-message: <some_message>
-date: <some_date>
Whenever a new message is sent to a user, he should get a notification.
I have thought about using Push Notification, i.e. I use Cloud Function Trigger to observe the path:
functions.database.ref('conversations/{uid}/{recipientId}/{messageId}').onCreate((snapshot) => {
// Send push notification to user with "uid"
})
However, there's a problem with this, what if the user blocks the push notification of the app? The user is not gonna receive any message while he's not using the app (which is what he wants by turning off push notification), but he's not gonna get any message even when he's in the app. Therefore, I'm thinking, maybe I should use Firebase SDK in my app to observe database like so:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
But then, this only observes newly started conversations, i.e. if the user already had a conversation with, say "person1", and "person1" sends a new message to the user, this observer wouldn't be triggered. Then, I was thinking:
Firstly, Keep the above observer so that I get notified when a new conversation is started
Secondly, Create multiple other observers that listen to my existing conversations:
Database
.database().reference()
.child("conversations").child(<my_user_id>).child(<existing_recipient_id>)
.observe(.childAdded) { (snapshot) in
// do stuff with snapshot
}
But this way, how do I know all my "existing_recipient_id"? I certainly shouldn't fetch them on start up:
Database
.database().reference()
.child("conversations").child(<my_user_id>)
.observeSingleEvent(of: .value) { (snapshot) in
// Extract all "existing_recipient_id"
}
Because this fetches all my conversations and their messages, which could potentially be multi-GBs.
I have the following 2 questions:
If I have 1,000 conversations with 1,000 people, should I have 1,000 observers in-app? If this wouldn't cause any problem, say performance issue, how do I set up these observers so that I could avoid the problems above?
I'm definitely using push notification, in case user is not in the app while a new message is sent to him. But, I don't know whether the user is in app or not, if he is, I already have those observers, push notification seems redundant, and it raises the cost. Is there a way that I can avoid this?
Temp solution
Write a cloud function that fetches all "existing_recipient_id", which is just an array of strings.
In the app, I add a listener that monitors the device's connection state, whenever the device comes back online from offline, also when the app first launches, I call that cloud function to fetch id's of all existing conversations.
Add observers to each of those conversations
Add observer to listen to new conversation
But I still don't know what to do about push notification when user is in-app, I guess I'll do it even though it's redundant

Not receiving push notifications for deleted events?

I have a calendar tool that integrates with Outlook Calendar. To respond to changes on the Outlook side, I subscribe to push notifications. If I miss the first notification of a change, Outlook sends others with ChangeType: 'Missed' and I synchronize with the user's calendar to retrieve the details of the change. However, deleted events do not seem to be included in the sync response.
The documentation suggests that it is possible to get deleted events:
Synchronize and get new, updated, or deleted events in a specified time range from the user's primary calendar (../me/calendarview) or from a different calendar.
There is even a section about deleted events and synchronization.
Deleted events will contain a reason property with the value of "deleted" to indicate a deleted entity. If the event is a recurring master event, you should delete all of the occurrences and exceptions.
'Created' and 'Updated' ChangeTypes work fine.
Am I subscribing incorrectly? Or is this not a feature of the Outlook Calendar API?
Here is the body of my subscription request:
{
'#odata.type': '#Microsoft.OutlookServices.PushSubscription',
'Resource': "https://outlook.office.com/api/v2.0/me/calendars/#{calendar_id}/events",
'NotificationURL': MY_URL,
'ChangeType': 'Created, Updated, Deleted',
'ClientState': 'foo',
'SubscriptionExpirationDateTime': TTL.minutes.from_now.iso8601
}

How to send a Firebase Notification when new data is available to user?

I have a coaching app that has a section where I can push realtime updates out to the players like: "No Practice - Do to inclement weather, practice will be pushed until Friday"
I have been trying to figure out how to send automatic notifications when I update this UpdatesTableView with a new post. Like "New Update Posted".
I post my updates to the Firebase Database. There must be a way to listen for changes and when there is to push a notification out to all the users?
I already have firebase notifications set up in my app but I have to utilize the Firebase console to push these notifications every time i push an update. Does anyone know how to automate this? Thanks!
You can easily do that by listening/Observing to any data change at a particular location in firebase. If new child is added to that path, associated block will be called.
In your case, you can observe UpdatesTableView. and whenever you post any update, call the block which will send notification to all users.
If you are using Swift:
func observe(_ eventType: FIRDataEventType, with block: #escaping (FIRDataSnapshot) -> Void) -> UInt
If you are using Objective C:
- (FIRDatabaseHandle)
observeEventType:(FIRDataEventType)eventType
withBlock:(nonnull void (^)(FIRDataSnapshot *_Nonnull))block;
According to official firebase documentation :
observeEventType:withBlock: is used to listen for data changes at a particular location. This is the primary way to read data from the
Firebase Database. Your block will be triggered for the initial data
and again whenever the data changes.
And, Whenever you would like to stop listening to data changes, you can Use removeObserverWithHandle
Use removeObserverWithHandle: to stop receiving updates. - parameter:
eventType The type of event to listen for. - parameter: block The
block that should be called with initial data and updates. It is
passed the data as a FIRDataSnapshot. - returns: A handle used to
unregister this block later using removeObserverWithHandle:
For more and detailed information, Read iOS firebase#Attaching Observers to read data Documentation.
Also, For sending Notifications to users effieciently, you can use Firebase Notification. Have a look at it. i dont know about your usecase properly, But i think this will help.
I also stucked with same problem where I wanted to show notification to users whenever data changes in Firebase irrespective of application in foreground or background.
I achieved it by binding ChildEventListener with a service which keeps running in background. At every childAdded event data is stored in sqlited db and a new notification object is created and shown to user.

Handle Push Notification infos before login

My question is about a best practice to use to handle a push notification in a defined scenario.
My app has 3 ViewControllers:
Login: User authenticates to start using the app
TableView: A simple table view with a contacts like appearance
DetailView: A simple viewController containing details from selected row of TableView
I receive a remote notification with some info in the payload (let's say a phone number for example). I need to use that info on DetailView but at receiving time I'm not logged in (app not running), so I press notification and it opens my app (Login) but I need to keep somewhere notification payload (or an object created from it) and pass it to DetailView.
So question is:
what is best practice to pass data from the notification to an inner ViewController, if the notification is received before user is logged in?
My only solution right now is: evaluate an object in didReceiveRemoteNotification, keep it in AppDelegate and access it everytime user's login to open DetailView if object is present (and clean it after using of course) but I don't think it is a good one.
Any suggestion?
What you said is mostly right because the only place you will receive a notification in is your app delegate.
but keeping a global object with the data is not the right thing to do, specially if you would like to respect design pattern and isolation between the classes.
as I understand from you the data you will get in the payload will be used in other screens in the app, so what I think the best is :
save it in User defaults or data base and access it when ever you need, and keep overriding it every time you a new notification.
if you would like to use the data base option I would like to recommend you to use Realm as it way much easier than core data and didn't take much time implementing it.
Hint: if this is the only kind of data you gonna save in the app then use User defaults.
hope this answer your question
try to save this data in User Defaults then, when you are logged in, get the data from User Defaults. Second option - set some variable and initialize it whit this data, and after that pass the data to new ViewController/

How can I distinguish internal from external updates in Firebase

I'm using iOS/Swift with Firebase as my backend.
When the value of a reference change, I get notified, because I'm adding an observer.
What I need is to be able to know when this change was triggered from my local code or from the server.
You can simply add a child to your reference which stores the uid of the user that updated the reference and compare it with the current app user

Resources