Push notification to multiple devices using rapns ( on Rails ) - ruby

If I want to push notification to multiple devices (e.g. 1000+ devices) using rapns on Rails, could I just create one Rapns::Notification instance?
I try to assign an array included all device tokens to variable "device_token", but it always just returns nil at all. Thus I have to create as much Rapns::Notification instances as the number of the device. Is that right? Or any better way to push?

I am not that far in implementing rapns, but I guess you will have to create a new notification entry for each device_token.

Related

Storing room data on Socket.io

I am making a web app with Socket.io and I want to store data for each of the rooms. The data includes some data about users, as well as the room itself, etc., all in a JavaScript object.
Now my question is if I simply have an array let rooms = [] on my server.js which I manipulate and use to store data, would that be OK?
If I deploy to production and have users on the site, would this be fine and work as expected? I am not sure if I need to implement a DB here. Thoughts?
It really depends on what you want to get out of it. Using local state (i.e. what you are doing with let rooms = []) will work just fine (I've done this and had success with it).
The downside is that your state will be in one server's memory. So if that server goes down or you restart it, you will lose all that state (all your rooms). Also, if you need to scale beyond one server then this won't work because each server would have a different list of room data. Your clients would get a different view of things depending on which server they connect to.
The reason this approach has worked for me previously was because my data was very transient and I could accept losing it. I also did not have scaling needs.
In summary, if your situation is such that:
you won't have more users than you can handle on one server instance at any given time
it's okay if your data gets reset
Then go ahead with this - it worked great for me! Otherwise, if you want to make sure your room data doesn't get reset or if you need more than one server, you will want something like a database.

Can I add assigns to the “main socket” after the connection is already established?

As explained by this post, when the client first connects with the server, a “main socket/process” gets created and holds its assigns. Later, when the client joins specific channels/topics, each channel’s socket/process copies those assigns and can add to them as it will.
I now have a use case where, upon the user joining their own individual channel (i.e. user:#{user_id}), I retrieve some information about the user from the DB, which should then be globally available to all channels this user later joins. However I haven’t been able to find a way to put those information into socket.assigns so that they can be available everywhere. If I try to assign them, they will only be available in the socket.assigns of this particular user:#{user_id} channel.
Is there a way to do it? Should I just instead simply try to fetch all those information in one go when the user first connects, instead of when they join the individual user channel?
Different channels mean different sockets.
The easiest solution would be to maintain the permanent state (Agent, ETS, DETS, mnesia, ...), holding a map user_id => user_info and query this state whenever you need this info.

Sending a list of assets to android wearable device

Reading the docs (https://developer.android.com/intl/es/training/wearables/data-layer/assets.html), there is a method putAsset to transfer assets to the wear/mobile devices. I'd like to know if there is a way to transfer a list of assets instead of sending them 1 by 1. (putStringArrayList for a string list for example)
No, you have to do that one by one, there is no bulk operation for adding data items.

How to implement saveEventually in CloudKit

One of true greatest Parse features is PFObject's saveEventually method. From Parse’s doc:
saveEventually
Saves this object to the server at some unspecified time in the future, even if Parse is currently inaccessible.
Basically it saves it locally and keeps trying to push Parse whenever it feels there is a connection.
How can someone implement the same functionality using CloudKit?
In CloudKit you have to do everything yourself.
You could set the object in a queue (in memory and persist to file in case of an app restart) When the object is saved to CloudKit, you can remove it from the queue.
You could create a special queue object that would contain the actual data plus some extra information like timestamps and retry count.
In your AppDelegate application didFinishLaunchingWithOptions you should read the queue from file and continue processing

iBeacon Department Store Scenario - Ranging vs. Monitoring

So we are trying to put together a scenario with iBeacons and I think we are getting stuck with the differences between ranging and monitoring in the background and now i'm not sure what we want to do is possible.
We have 500 stores that we want to deploy iBeacons to. The purpose of the beacon is to greet the customer with a notification and a coupon (sometimes). What we would like to do is utilize a single UUID with the major being the store number and the minor being type of store (regular store vs. kids. A kids store can be connected to a regular store). Ideally, once a iBeacon with our UUID is found, we would like our app to pull an XML file from our website specific to the major number (store number), display a notification welcome message (possibly stating 'we have a coupon for you' depending on what the xml file says), and save the xml file data to the app so the user can retrieve the coupon if they open the app. This all seems possible with the application in the foreground, but we seem to be having difficultly getting it to work in the background. Is what I am describing possible and should I be thinking of a different way to do this?
Thanks
Yes, you can do this. The trick is that you need to combine both ranging and monitoring at the same time. Monitoring is needed to launch your app into the background. Ranging is needed to get the specific ids of the Beacons you see.
Set it up like this:
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:#"blah"];
region.notifyOnEntry = YES;
[self.locationManager startMonitoringForRegion:region];
[self.locationManager startRangingBeaconsInRegion:region];
As soon as this happens, you will get ranging callbacks for about five seconds before the application goes back to sleep, and this method will get called once per second:
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
if (!_firstOneSeen) {
_firstOneSeen = true;
// Do something with beacons array here. read out the major/minor and get the
// notification message from your XML web service
}
}
Two notes of caution:
Monitoring iBeacon Regions in the background can be a little tricky, and it can take longer than you might think to get callbacks. See this detailed discussion.
You only have five seconds from when your app is woken up until it goes back to sleep, so your web site better respond very quickly. A safer idea that would work across network dropouts would be to fetch the XML up front and cache it inside your app so it is ready to go even if there is a network dropout.
My company, Radius Networks makes a library and web service called ProximityKit that does this up-front caching of beacon-specific key/value pairs that you can configure with your web browser. That way, you don't have to write the web service yourself.

Resources