Giter Club home page Giter Club logo

parselivequery-ios-osx's Introduction

Parse LiveQuery Client for iOS/OSX


⚠️ The LiveQuery feature has been added as a module to the Parse Apple SDK. This repository is archived and will no longer receive any updates.


Platforms Carthage compatible Podspec License ci release Build Status Join The Conversation Backers on Open Collective Sponsors on Open Collective Twitter Follow

PFQuery is one of the key concepts for Parse. It allows you to retrieve PFObjects by specifying some conditions, making it easy to build apps such as a dashboard, a todo list or even some strategy games. However, PFQuery is based on a pull model, which is not suitable for apps that need real-time support.

Suppose you are building an app that allows multiple users to edit the same file at the same time. PFQuery would not be an ideal tool since you can not know when to query from the server to get the updates.

To solve this problem, we introduce Parse LiveQuery. This tool allows you to subscribe to a PFQuery you are interested in. Once subscribed, the server will notify clients whenever a PFObject that matches the PFQuery is created or updated, in real-time.

Setup Server

Parse LiveQuery contains two parts, the LiveQuery server and the LiveQuery clients. In order to use live queries, you need to set up both of them.

The easiest way to setup the LiveQuery server is to make it run with the Open Source Parse Server.

Install Client

Cocoapods

You can install the LiveQuery client via including it in your Podfile:

pod 'ParseLiveQuery'

Use Client

The LiveQuery client interface is based around the concept of Subscriptions. You can register any PFQuery for live updates from the associated live query server, by simply calling subscribe() on a query:

let myQuery = Message.query()!.where(....)
let subscription: Subscription<Message> = Client.shared.subscribe(myQuery)

Where Message is a registered subclass of PFObject.

Once you've subscribed to a query, you can handle events on them, like so:

subscription.handleEvent { query, event in
    // Handle event
}

You can also handle a single type of event, if that's all you're interested in:

// Note it's handle(), not handleEvent()
subscription.handle(Event.created) { query, object in
    // Called whenever an object was created
}

By default, it will print the logs from WebSocket / WebSocketDelegate. You can turn it off:

Client.shared.shouldPrintWebSocketLog = false

You can also enable socket trace messages for all sent and received strings. By default, these trace messages are disabled.

Client.shared.shouldPrintWebSocketTrace = true

Handling errors is and other events is similar, take a look at the Subscription class for more information.

Advanced Usage

You are not limited to a single Live Query Client - you can create your own instances of Client to manually control things like reconnecting, server URLs, and more.

How Do I Contribute?

We want to make contributing to this project as easy and transparent as possible. Please refer to the Contribution Guidelines.


As of April 5, 2017, Parse, LLC has transferred this code to the parse-community organization, and will no longer be contributing to or distributing this code.

parselivequery-ios-osx's People

Contributors

acinader avatar ananfang avatar bryandel avatar cbaker6 avatar dblythy avatar dependabot[bot] avatar drdaz avatar ephread avatar felix-dumit avatar flovilmart avatar heeaad avatar jlnquere avatar jlott1 avatar joeszymanski avatar junya100 avatar kajensen avatar lacker avatar maxkattner avatar mrmarcsmith avatar mtrezza avatar natanrolnik avatar nlutsenko avatar noobs2ninjas avatar rafaelmaroxa avatar richardjrossiii avatar rogerhu avatar rostopira avatar tmg-mlyons avatar tomwfox avatar vstepanyuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parselivequery-ios-osx's Issues

Best practice to use the data in a tableview from the LiveQuery

Because it's really new and documentation is not available, making our own documentation. I receive the data and I have tried many ways to add this data to a tableview with

import UIKit
import Parse
import ParseLiveQuery

let liveQueryClient = ParseLiveQuery.Client()

class TestLiveQuery: UIViewController {

 var messageObjects = [PFObject]()

private var subscription: Subscription<Message>?

var myQuery: PFQuery {
    return (Message.query()?
        .whereKey("roomName", equalTo: "test")
        .orderByAscending("createdAt"))!
}

override func viewDidLoad() {
    super.viewDidLoad()


    let username = "Tes"
    let password = "testtest"

    PFUser.logInWithUsernameInBackground(username, password: password).continueWithBlock { task in
        return nil
    }

    self.printPriorMessages()
    self.subscribeToUpdates()

}




@IBAction func sendMessageButton(sender: AnyObject) {

    let message = Message()
    message.author = PFUser.currentUser()
    message.authorName = message.author?.username
    message.message = "Hello: \(NSDate().toShortTimeString())"
    message.room = PFObject(withoutDataWithClassName: "Room", objectId: "rzCQzJbRzF")
    message.roomName = "test"
    message.saveInBackground()

}

func printPriorMessages() {
    myQuery.findObjectsInBackground().continueWithBlock() { task in
        (task.result as? [Message])?.forEach(self.printMessage)
        return nil
    }
}

func subscribeToUpdates() {
    subscription = liveQueryClient
        .subscribe(myQuery)
        .handle(Event.Created) { _, message in
            self.printMessage(message)
    }
}

private func printMessage(message: Message) {
    let createdAt = message.createdAt ?? NSDate()
    print("\(createdAt) \(message.authorName ?? "unknown"): \(message.message ?? "")")
}
}

extension NSDate {

func toShortTimeString() -> String {
    let formatter = NSDateFormatter()
    formatter.timeStyle = .ShortStyle
    let timeString = formatter.stringFromDate(self)

    return timeString
}
} 

by doing this

func printPriorMessages() {
    myQuery.findObjectsInBackground().continueWithBlock() { task in
        (task.result as? [Message])?.forEach(self.printMessage)
        print("printPrioMessages")
        self.tableView.reloadData()
        return nil
    }
}

func subscribeToUpdates() {
    subscription = liveQueryClient
        .subscribe(myQuery)
        .handle(Event.Created) { _, message in
            self.printMessage(message)
            print("subscribe updates")
            self.messageObjects.append(message)


            let insertionIndexPath = NSIndexPath(forRow: self.messageObjects.count - 1, inSection: 0)
            self.tableView.insertRowsAtIndexPaths([insertionIndexPath], withRowAnimation: .Automatic)

            print(self.messageObjects.count)


    }
}

private func printMessage(message: Message) {
    let createdAt = message.createdAt ?? NSDate()
    //print("printMessage")
    self.messageObjects.append(message)
    print("\(createdAt) \(message.authorName ?? "unknown"): \(message.message ?? "")")
}

But it's getting messy and crashing etc... So if somebody has a working example, I want to load the data in a tableview and if it's getting new data insert a row with the new data in the tableview.

Value of type 'PFQuery<PFObject>' has no member 'subscribe'

Hello,

I just updated my project for swift 3 and when I'm trying to subscribe with query its giving me this error.

Value of type 'PFQuery<PFObject>' has no member 'subscribe'
I was using this code in swift 2.
subscription = query.subscribe()

ParseLiveQuery ObjC

Since there is little info available about live query in ObjC, I'm trying to understand the concept by doing trial and error. So far, I have managed to include the ParseLiveQuery 1.0.1 in my project (not without overcoming a few issues first).

Now, I am testing the code and see how the callback works. Therefore I have the following method:

`

-(void) liveQuerytest {
__weak typeof(self) weakSelf = self;

//Init the Client
//self.client = [[PFLiveQueryClient alloc] init];
self.client = [[PFLiveQueryClient alloc] initWithServer:PARSE_SERVER
                                          applicationId:PARSE_APPLICATION_ID
                                              clientKey:PARSE_CLIENT_KEY];

PFQuery *OnlineQ = [PFQuery queryWithClassName:@"TestingClass"];

[OnlineQ whereKey:@"objectId" equalTo:@"TR9nmpKp8"];

[OnlineQ orderByAscending:@"createdAt"];

//NSLog(@"This is the query: %@", [OnlineQ findObjectsInBackground]);

[OnlineQ findObjectsInBackgroundWithBlock:^(NSArray * _Nullable objects, NSError * _Nullable error) {
    if (!error) {

        NSLog(@"The objects: %@", objects); 
        weakSelf.subscription = [[weakSelf.client subscribeToQuery:OnlineQ] addCreateHandler:^(PFQuery * query, PFObject * obj) {
            NSLog(@"The object that has changed: %@ %@",obj.createdAt, obj.objectId);
        }];

        NSLog(@"the subscription status: %@", self.subscription);

    }
}];
  }

`

Now the query works fine and I received the objects as it suppose to. For testing purpose, I am updating the class with the following cURL:

curl -X PUT \ -H "X-Parse-Application-Id: XXXXXXXXXXXXXXXXXXXX" \ -H "X-Parse-MASTER-Key: XXXXXXXXXXXXXXXXX" \ -H "X-Parse-Url: http://localhost:1337/parse" \ -H "Content-Type: application/json" \ -d '{"testing":"other test is done"}' \ http://localhost:1337/parse/classes/TestingClass/TR9nmpKp8

The update is done properly, but I dont see any changes in the client in the subscription. It is the correct way to go about this and why the callback is not working.

Thanks for any info that you can bring to solve this issue.

Error on project build

Hello,
I get error when building app

Value of optional type 'ParseClientConfiguration?' not unwrapped; did you mean to use '!' or '?'?

Error is in Client.swift file on line 40.

Same errors are in same file on line 64, 65, 99, 100 and 101.

Can you please tell me , what is wrong?

What's going on with this repo?

There are many things stopping this library from being useful let alone useable in production. I can see this being an incredibly useful addition to the parse framework but it is simply not ready yet. No support for pointers (pfgeopoints, dates), compound queries, multiple subscriptions.. to me are necessary at the bare minimum.

Is anyone taking the lead contributing to this? I'm happy to help but i'm not sure how to get started.

LiveQuery does not work with PFObjects secured with an ACL & when the where key has a Pointer

First, thanks to the Parse team for making Parse open source and enhancing it constantly.

Environment:

  • parse: 1.8.5
  • parse-server: 2.2.11
  • node: 4.4.5

Parse-server index.js:

...
var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/xxxx-dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || 'xxxx',
  masterKey: process.env.MASTER_KEY || 'xxx',
  serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',
  filesAdapter: new S3Adapter(xxxx),
  liveQuery: {
    classNames: ["Account", "GUEvent"]
  }
});
...
ParseServer.createLiveQueryServer(httpServer);

iOS Client:

class viewController: UIViewController {
    private var subscription: Subscription<GUEvent>!

    override func viewDidLoad() {
        super.viewDidLoad()

        subscription = GUEvent.query()!.whereKey("account", equalTo: accountObject).subscribe()
        subscription.handleEvent { query, event in
             print("Handling Event")
        }
    }
}

Live Query does not work:

  • When the objects in GUEvent are secured with an ACL but works when the objects are publicly readable & writable.
  • When the account is a pointer, I get *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write'.

So far Live Query works:

  • When the objects in GUEvent are publicly readable and writable.
  • When the where statement does not contain a pointer.

Any help would be greatly appreciated.

Singleton classes for Client.shared and socket reconnect

Not sure if anyone else agrees, but it seems kind of a pain to have to initialize the client yourself then set shared to your initialization. Unless im doing something wrong.

Also, Im having to call Client.shared.reconnect() before I can even do a query.subscribe().Otherwise SRWebSocket throws the following

Invalid State: Cannot call send: until connection is open

Ive actually actually have started rewriting shared as a proper singleton already I just didn't know if this was meant to function this way for a reason. I didn't show that reconnect or socket was set in the main init.

Also I noticed that disconnect boolean used in subscribe is set in disconnect() but not reconnect(). In those same reguards some of the subscribe logic seems backwards. Disconnected seems like it would default to true so that you could simply go

if socket == nil || disconnected{ reconnect() }

I just found out on another thread that what is currently in place should be acting as a singleton.

Perhapse this works better if I where to do whats in the repository example of

let liveQueryClient = ParseLiveQuery.Client(server: "http://localhost:1337")

subscription = liveQueryClient
            .subscribe(messagesQuery)
            .handle(Event.Created) { _, message in
                self.printMessage(message)

I havent tried it but this is not the way it says it works on the main page here. All im doing is query.subscribe() and I get Invalid State: Cannot call send: until connection is open

I have to do

        let client = Client.init()
        Client.shared = client
        Client.shared.reconnect()

and not a line less or else it will throw the error mentioned above

Subscribe without params not work?

I create query without params where and want to subcribe. But handle error: "
Error: ServerReportedError(code: 1, error: "Missing required property: where", reconnect: true)"

Server side configuration causing deployment errors

@nlutsenko

I'm on google app engine and implementing the liveQuery server in server.js is preventing my app from deploying. I'm not sure if it's my implementation or what but removing the live query code works but implementing it stops deployment.

push: {
      ios: {
        pfx: __dirname  + '/cloud/ParsePushDevelopmentCertificate.p12',
        bundleId: 'com.bundleId.appName',
        production: false
      }
    }
  liveQuery: {
    classNames: ['Message', 'Room'];
  }
});

// Mount the Parse API server middleware to /parse
app.use(process.env.PARSE_MOUNT_PATH || '/parse', parseServer);

app.get('/', function(req, res) {
  res.status(200).send('Be Real');
});

var server = app.listen(process.env.PORT || 8080, '0.0.0.0', function() {
  console.log('App listening at http://%s:%s', server.address().address,
    server.address().port);
  console.log('Press Ctrl+C to quit.');
});

// Initialize a LiveQuery server instance, app is the express app of your Parse Server
let httpServer = require('http').createServer(app);
httpServer.listen(port);
var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer);

Provide Swift LiveQuery use case example for Realtime Messaging

Environment Setup

MongoLab(mLab), Google App Engine...
@wangmengyan95 @richardjrossiii

Since iOS docs aren't released yet i'm still struggling to implement live queries on the client side.
So I'd like to get an example for how it could be use to send/recieve realtime messages in a messaging app using a method I'm using in my own chat app which was previously using push notifications.

How could I implement liveQueries in this method to send/receive realtime messages?

// MARK: - LOAD MESSAGES
    func loadMessages() {

        print("Loading messages...")
        var lastMessage:JSQMessage? = nil

        if messages.last != nil {
            lastMessage = messages.last
        }

        let messageQuery = PFQuery(className: "Message")
        messageQuery.whereKey("room", equalTo: self.room!)
        messageQuery.orderByAscending("createdAt")
        messageQuery.limit = 500
        messageQuery.includeKey("user")

        if lastMessage != nil {
            messageQuery.whereKey("createdAt", greaterThan: lastMessage!.date)
        }

        messageQuery.findObjectsInBackgroundWithBlock { (results: [PFObject]?, error:NSError?) -> Void in

            if error == nil {

                if results != nil {

                    let messages = results

                    for message in messages! {

                        self.messageObjects.append(message)

                        let user = message["user"] as! PFUser
                        self.users.append(user)

                        let chatMessage = JSQMessage(senderId: user.objectId , displayName: user.objectForKey("name") as! String, text: message["content"] as! String)
                        self.messages.append(chatMessage)

                        Answers.logCustomEventWithName("Messages Loaded", customAttributes: nil)

                    }
                }

                if results?.count != 0 {
                    self.finishReceivingMessage()
                }

            }
        }

    }

Don't think my send method is needed but here it is either way.

   //MARK: - SEND MESSAGES
    override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {

        let message = PFObject(className: "Message")
        message["content"] = text
        message["room"] = self.room
        message["user"] = PFUser.currentUser()

        message.saveInBackgroundWithBlock { (success: Bool, error:NSError?) -> Void in

            if error == nil {

                self.loadMessages()
                //self.sendPushToContact()
                self.room!["lastUpdate"] = NSDate()
                self.room?.saveInBackgroundWithBlock(nil)
                Answers.logCustomEventWithName("Send Message", customAttributes: nil)

            } else {

                print("Error while sending message \(error?.localizedDescription)")
            }
        }
        self.finishSendingMessage()
    }

No errors, no results

I have been banging my head against the table trying to get Parse live working. But no matter what I do I can't get it to work. Mind you there are no connection errors. Here is a simple file.

class ViewController: UIViewController {

    var liveQueryClient: ParseLiveQuery.Client?
    private var subscription: Subscription<Beacon>?

    var beaconQuery: PFQuery {
        return (Beacon.query()?.whereKey("beaconName", equalTo: "beacon5"))!
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        liveQueryClient = ParseLiveQuery.Client(server: "URLISHERE")

        subscription = liveQueryClient!
            .subscribe(beaconQuery)
            .handle(Event.Updated) { _, message in
                print("It Works....")
        }

    }

}

Any help would be wonderful.

PFGeopoint, PFFile not converted

When Update,Create or other events are received PFObject is not generated correctly.

Instead of

<PFGeoPoint: 0x1360a4490, latitude: 42.722461, longitude: 45.792475>

I got this assigned to my PFUser subclass location property:

{
    "__type" = GeoPoint;
    latitude = "42.72246132158908";
    longitude = "45.79247540719969";
}

Same happens with PFUser avatar property and all PFObjects, PFPointers and etc

In ClientPrivate.swift i added

if value is Dictionary<String,AnyObject>{
   let objectType = value.valueForKeyPath("__type") as? String;
   let lat = value.valueForKeyPath("latitude") as? Double;
   let lng = value.valueForKeyPath("longitude") as? Double;
   if(key == "location" && objectType == "GeoPoint"){
       let geoPoint:PFGeoPoint = PFGeoPoint.init(latitude: lat!, longitude: lng!)
           parseObject[key] = geoPoint;
       }
   }
}

After this change GeoPoint is assigned to PFUser subclass as needed, but i am not very familiar with swift and don't think my solution is good, any ideas @nlutsenko @richardjrossiii ?

Handler at Subscription.handle is not called in main queue

The handler block at class Subscription -> functionhandle(eventType: T -> Event<T>, _ handler: (PFQuery, T) -> Void) -> Subscription is called in from Queue com.parse.livequery.
Shouldn't be called from main queue (com.apple.main-thread)?

Subscription callbacks not firing (Obj-C)

Related

#39
#36
#28
#36
#41
#7

I have been pulling my hair out for hours to debug this (dippin toes in Swift)

Here are my recollections of my memory of this trip down the rabbit hole for others:

1) Could not build module Parse

screen shot 2016-06-08 at 05 29 33

Downloading Parse and ParseLiveQuery was ok, but whenever I build the project I get the error as in the title.

It seems to go away (for 1 build, or not at all) when doing a (super) clean build, it seems I can ignore it, because the app builds fine.

2) Invalid Sec-WebSocket-Accept response

Now I had a connection problem, the error I got was

Error: Error Domain=SRWebSocketErrorDomain Code=2133 "Invalid Sec-WebSocket-Accept response" UserInfo={NSLocalizedDescription=Invalid Sec-WebSocket-Accept response}

After a lot of messing with my nginx configuration I figured out it had to do with my proxy setup.

There are a couple of issues about it over at SocketRocket 1 2 3

I forked ParseLiveQuery and updated the SocketRocket dependency, which made the above error go away, but gave me another one.

Updating Parse and ParseLiveQuery to master seemed to have resolved this.

3) No errors ?

Sometimes errors only showed up when stepping through the code, this might have to do with the Obj-C >< Swift interop?

After a while, I got the error to show that I was missing a where clause on the query

4) Similarity to Parse-JS

  • The where clause on a query is not obligatory in Parse-JS

screen shot 2016-06-08 at 14 42 41

- The `sessionToken` is always sent (https://github.com/ParsePlatform/ParseLiveQuery-iOS-OSX/blob/3daca2f89a3869d026b1005dda57852012321836/Sources/ParseLiveQuery/Internal/Operation.swift#L21) from Parse-JS, this is only sent when logged in, this shouldn't matter though, just putting it out there. ### 5) Moar logging!

I started adding log statements to the ParseLiveQuery library, and saw that it was getting a connection, and sent subscriptions to the websocket connection (please add a flag for verbose logging!)

Because of the logs I noticed that I was querying an object that wasn't setup for live query (e.g. wasn't added to the liveQuery config for the parse server)

So I changed that and finally got responses back from the server

6) Callbacks don't fire

This is the real issue, I see the data is coming in when logging raw websocket data (or checking the Network traffic)
But the registered callback is not firing:

[Parse initializeWithConfiguration:[ParseClientConfiguration configurationWithBlock:^(id<ParseMutableClientConfiguration> configuration) {
    configuration.applicationId = @"*****";
    configuration.clientKey = @"*****";
    configuration.server = @"https://devparse.*****";
    configuration.localDatastoreEnabled = NO;
    NSLog(@"Connecting to: %@", configuration.server);
}]];

self.client = [[PFLiveQueryClient alloc] initWithServer:@"https://devparse.*****" applicationId:@"*****" clientKey:@"*****"];
PFQuery *query = [PFQuery queryWithClassName:@"Messages"]; // <-- make sure you register the object in the parse-server config
[query whereKey:@"objectId" notEqualTo:@"whut"]; // <-- make sure you add a where clause

Test 1:

self.subscription = [self.client subscribeToQuery:query];
[self.subscription addCreateHandler:^(PFQuery * query, PFObject * message) {
    NSLog(@"LQ!!");
}];

Test 2:

self.subscription = [self.client subscribeToQuery:query];
[self.subscription addCreateHandler:^(PFQuery * _Nonnull query, PFObject * message) {
    NSLog(@"LQ!!");
}];

At this moment, my versions of things are:

  • Parse, ParseLiveQuery, CocoaPods -> master branch
  • XCode -> 7.3.1

7) Possible cause?

944065d

8) Working work around

I had seen enough off the code after this debug session to come up with the following, which seems to work:

@import Foundation;
@import Parse;
@import ParseLiveQuery;

#import "AppDelegate.h"

@interface UCMessageHandler : NSObject <PFLiveQuerySubscriptionHandling>
@end

@implementation UCMessageHandler
- (void)liveQuery:(PFQuery *)query didRecieveEvent:(PFLiveQueryEvent *)event inClient:(PFLiveQueryClient *) client {
    NSLog(@"CREATED EVENT TYPE: %d", PFLiveQueryEventTypeCreated);
    NSLog(@"UPDATED EVENT TYPE: %d", PFLiveQueryEventTypeUpdated);
    NSLog(@"REMOVED EVENT TYPE: %d", PFLiveQueryEventTypeDeleted);
    NSLog(@"EVENT: %@", event);
    NSLog(@"EVENT TYPE: %d", event.type);
    NSLog(@"EVENT OBJECT: %@", event.object);
//    NSLog(@"LQ!!!!!!!!!!!!!!!!!");
}
@end

@interface AppDelegate ()
@property (nonatomic, strong) PFLiveQueryClient *client;
@property (nonatomic, strong) PFQuery *query;
@property (nonatomic, strong) UCMessageHandler *handler;
@property (nonatomic, strong) PFLiveQuerySubscription *subscription;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    [Parse initializeWithConfiguration:[ParseClientConfiguration configurationWithBlock:^(id<ParseMutableClientConfiguration> configuration) {
        configuration.applicationId = @"****";
        configuration.clientKey = @"****";
        configuration.server = @"https://devparse.******.***";
        configuration.localDatastoreEnabled = NO;
        NSLog(@"Connecting to: %@", configuration.server);
    }]];

    // Setup livequery client
    self.client = [[PFLiveQueryClient alloc] initWithServer:@"https://devparse.******.***" applicationId:@"****" clientKey:@"****"];

    PFQuery *query = [PFQuery queryWithClassName:@"Messages"]; // <-- make sure to get a type that is enable in parse server liveQuery config
    [query whereKey:@"objectId" notEqualTo:@"whut"]; // <-- make sure to add a where clause
    self.handler = [[UCMessageHandler alloc] init]; // <-- make sure to create a handler yourself by using the PFLiveQuerySubscriptionHandling protocol
    self.subscription = [self.client subscribeToQuery:query withHandler:self.handler]; // <-- make sure to use the custom object that implements the PFLiveQuerySubscriptionHandling protocol

    return YES;
}
@end

Looking forward to the responses!

@richardjrossiii care to take a look at this?

Assertion failure isDataAvailableForKey for updated event for null pointers. (swift)

Steps to reproduce: save an object with a pointer column without setting the pointer. Observe that when a subscription event comes through (post-save) trying to access this pointer (even just to see if it is set) crashes with isDataAvailableForKey assertion failure.

Seems that there is an issue with setting the subclass with all variables including optionals. What is the solution?

I'm using the latest commit on master, e9eea48

(Also it would be awesome if includes worked with subscriptions)

Subscribe to receive local events

Would it be possible to subscribe to receive local events? For example if object is pinned to local datastore, event would be sent to subscribers. Or if saveEventually() is used, the local update event would be sent immediately and another event when the server receives the change. This would make easier to write client side code because usually you want to observe all events whether they are from local or remote changes.

Stream end encountered

I'm setting up a Live Query, and it doesn't seem to want to work. I think my server setup is correct:

var api = new ParseServer({
  databaseURI: databaseUri || '',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || '',
  masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
  serverURL: process.env.SERVER_URL || 'https://my.domain.com:1337/parse',  // Don't forget to change to https if needed
  push: {
    ios: [
      {
        pfx: 'keys/PushDev.p12', // Dev PFX or P12
        bundleId: 'com.id',
        production: false // Dev
      }
      // {
      //   pfx: '', // Prod PFX or P12
      //   bundleId: '',  
      //   production: true // Prod
      // }
    ]
  },
  liveQuery: {
    classNames: ["LiveClass"] // List of classes to support for query subscriptions
  }
});

...
...
...

var port = process.env.PORT || 1337;
var httpServer = require('https').createServer({
    key: privateKey,
    cert: certificate
}, app);

httpServer.listen(port, function() {
    console.log('server running on port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);

The only thing that's out of the ordinary is that I'm running with SSL on HTTPS. Does the LiveQuery server require any special setup for SSL?

When I create a live query, the console floods with:

code: 1001 reason: Stream end encountered

When I launch the server, I don't seem to get any error messages or anything and it appears to launch cleanly. What should I check?

After subscribing, no events handled, even though in React and websocket.org, it seems that the parse-server is working.

After lots of headaches, trials, errors and studying the examples, I couldn't receive any event on iOS after subscribing to Parse LiveQuery.

There's another thread on stack overflow with the same problem: http://stackoverflow.com/questions/37012451/livequery-not-responding

and now mine:
http://stackoverflow.com/questions/37381388/parse-livequery-subscription-doesnt-receive-any-events

I have configured a parse-server running LiveQuery on Amazon EC2 instance, on port 9091, with no proxy, firewall configurations made. It seems to be working fine, because we tested on React and using http://www.websocket.org/echo.html, telling that the connection was successful.

However on iOS, I couldn't make LiveQuery work, even though the handleSubscribe seems to be ok.

I've created a simple viewController to try it:

    import UIKit
    import Parse
    import ParseLiveQuery

    class StatsViewController: UIViewController {
        //MARK: - Outlets
        @IBAction func insertMessage(sender: AnyObject) {
            let message = Message();
            message.author = PFUser.currentUser()
            message.authorName = message.author?.username
            message.text = "Hello: \(NSDate())"
            message.roomName = "Test";

            message.saveInBackground();
        }

        //MARK: - Variables
        var myQuery: PFQuery {
            return (Message.query()?
                .whereKey("roomName", equalTo: "Test")
                .orderByAscending("createdAt"))!
        }

        var subscription: Subscription<Message>? = nil

        //MARK: - Lifecycle
        override func viewDidLoad() {
            super.viewDidLoad()

            //Registers the subclass
            Message.registerSubclass();
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

        override func viewDidAppear(animated: Bool) {

            //1) queries for messages, working.
            myQuery.findObjectsInBackground().continueWithBlock() { res in
                for msg in ((res.result as? [Message]))! {
                    print(msg);
                }
                return nil
            }

            //2) try to subscribe and receive any information from the server
            subscription = myQuery.subscribe()

            subscription!.handleEvent { query, event in
                // Handle event
                print("any event, please?"); //no events handled after creating a new message
            }

            subscription!.handle(Event.Created) { query, object in
                // Called whenever an object was created
                print("any creation, please?"); //no events handled after creating a new message
            }

            subscription!.handleError { (query, err) in
                print("any error, please?"); //no errors handled
            }

            subscription!.handleSubscribe { query in
                print("subscribed")
            }
        }

    }

I also tried the subscription using the code in the parse example, like in

func subscribeToUpdates() {
    subscription = liveQueryClient
        .subscribe(messagesQuery)
        .handle(Event.Created) { _, message in
            self.printMessage(message)
    }
}

some information

  • subscriptions.handleSubscribe: prints "subscribed", but there's no way to check if it was successful
  • after inserting a new message or deleting a record on parse-dashboard, there's no event to be handled on iOS
  • there's no error or log in the parse-server
  • running parse-server 2.2.10 at port 9091

Is there any mistake or something missing in the subscription process?

Thanks!

Compound live queries not supported

Versions

Parse iOS SDKs (1.13.0)
ParseLiveQuery iOS SDKs (1.0.1)
Parse Server (2.2.15)

Description

When trying to pass a compound queries to live server, the app crashes saying : Invalid type in JSON write (PFQuery).

The crash occurs at this line in ClientPrivate.swift :

internal func sendOperationAsync(operation: ClientOperation) -> Task<Void> {
    return Task(.Queue(queue)) {
        let jsonEncoded = operation.JSONObjectRepresentation
THIS LINE => let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonEncoded, options: NSJSONWritingOptions(rawValue: 0))
        let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)

        self.socket?.send(jsonString)
    }
}

The jsonEncoded details :

▿ 3 elements
  ▿ [0] : 2 elements
    - .0 : "requestId"
  ▿ [1] : 2 elements
    - .0 : "op"
    - .1 : subscribe
  ▿ [2] : 2 elements
    - .0 : "query"
    ▿ .1 : 2 elements
      ▿ [0] : 2 elements
        - .0 : className
        - .1 : Game
      ▿ [1] : 2 elements
        - .0 : where
        ▿ .1 : 1 elements
          ▿ [0] : 2 elements
            - .0 : $or
            ▿ .1 : 2 elements
              - [0] : <PFQuery: 0x7fb71bcf99d0> <= ISSUE
              - [1] : <PFQuery: 0x7fb71be38020> <= ISSUE

Support for compound queries (along with pointers, cf #16) would be great !

A simple test to test it's working LiveQuery

I search now the internet for everything I can't find to make this work, but with no documentation it's hard, the example chat is great, understand a lot, but it's not a working example, I tried over and over to make it work, it gives me some data from the query when I build the project, but no updates in the log console if I add a new object into the Message class

I want to make or see some example thats deadly simple and works so I can learn and make a realtime chat into my app

All I can find is not working projects and no explains about how it works... So if anyone can share some code or gives me hints, so we can make a real working example

Issue connecting/subscribing plz help

I've set up PLQ like:

I call listenToFriends() function in AppDelegate, and I also run

Friend.registerSubclass() on initial load.

I have a Friend.swift class like:
import Foundation
import Parse

class Friend: PFObject, PFSubclassing {
@NSManaged var fromUser: PFUser?
@NSManaged var toUser: PFUser?
@NSManaged var toUserString: String?
@NSManaged var fromUserString: String?
@NSManaged var status: String?

class func parseClassName() -> String {
    return "Friend"
}

}

// friend listener
func listenToFriends() {
Friend.registerSubclass()
let query = Friend.query()?.whereKey("fromUserString", equalTo: PFUser.currentUser()!.objectId!)
query?.getFirstObjectInBackgroundWithBlock({ (o:PFObject?, e:NSError?) in
print(o!) //this prints an obj so query works
})
let subscription: Subscription = query!.subscribe()
subscription.handle(Event.Created) {query, object in
print("Test")
}
}

can someone give me a pointer? livequery is set up on server. Also, interestingly enough.. if I use whereKey("fromUser",equalTo: PFUser.currentUser()) the query fails and app crashes, as we know only primitive objs are supported currently, but can someone shine some light on this as to why this fails?

Cant import ParseLiveQuery!!

Hi,

New to Swift.. When I run project.xcodeproj I can't import ParseLiveQuery... When I run project.xcworkspace I can't import Parse..

Can I get some insight? Using cocopods 1.0.1, using use_frameworks!

App crashes when subscribe to a query with Pointer constraints

I'm trying subscribe to a query that has a Pointer constraint (e.g. query.equalTo('user', Parse.User.current()))), but the app is crashing when tries to subscribe. The query is perfect because I tested with query.findObjectsInBackgroundWithBlock and runs and bring results.
Maybe internally it's not handling the Pointer correctly yet, accessing its objectId to be able to filter que query.

Swift 3 Error

Hello,

I'm getting 40 error on framework when I'm trying to build and run my project. Is Anyone facing an issue like this ?

ekran resmi 2016-09-26 16 59 05

Swift 3

Is anyone working on making this compatible with swift 3? Thanks!

LiveQuery Not working with PFUser

Hi,

I'm trying to use live query with pfuser. As shown on code.But I'm getting this error when I use PFUser in query.

let query = PFQuery(className: "Activity")
        query.whereKey("members", containedIn: [PFUser.currentUser()!])
        let subscription: Subscription<PFObject> = query.subscribe()
        subscription.handleEvent { (query, event) in
            print("event : \(event)")
        }

Error:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (PFUser)'

includeKey(s) not working?

When querying and using includeKey or includeKeys for Pointer-types, the referred objects are not loaded. Is this working as intended in ParseLiveQuery or am I doing something wrong?

Query declaration:

    var messagesQuery: PFQuery {
        return (Message.query()?
            .whereKey("roomId", equalTo: currentChatRoom!.objectId!)
            .includeKeys(["author", "room"])
            .orderByAscending("createdAt"))!

Subscription:

    subscription = liveQueryClient
        .subscribe(messagesQuery)
        .handle(Event.Created) { _, message in
            print("message author.objectId : \(message.author.objectId)")
        }

The last line produces error:
[__NSCFDictionary objectId]: unrecognized selector sent to instance

Can not find subscriptions under this class XXXX

In my app didFinishLaunchingWithOptions function
var userQuery: PFQuery { return (users.query()?.whereKey("name", equalTo: "ABC"))! }

   ` let liveQueryClient = ParseLiveQuery.Client()
    liveQueryClient
        .subscribe(userQuery)
        .handle(Event.Created) { _, user in
            print(user)
    }`

My PFQuery works if I use userQuery.findObjectsInBackground.
but nothing happens when I add a new row into the table.
I checked the error log in dashboard it says "Can not find subscriptions under this class users" whenever I add a new row.
How can I make the live query work?

Live query 1.0.1 release compiler errors

Ran pod update and installed latest version of 1.0.1 of the ParseLiveQuery Library.

Went to compile again and now receiving error in BoltsHelpers.swift

"Value of type 'TaskCompletionSource' has no member 'trySetError'

Installing Bolts (1.8.4)
Installing Bolts-Swift (1.2.0)
Installing BuddyBuildSDK (1.0.9)
Installing CardIO (5.3.2)
Installing Crashlytics (3.7.2)
Installing Fabric (1.6.7)
Installing IQKeyboardManagerSwift (4.0.4)
Installing Parse (1.14.2)
Installing ParseLiveQuery (1.0.1)
Installing SidebarOverlay (3.0.0)
Installing SocketRocket (0.5.1)
Installing Stripe (8.0.3)

these are my pod files and versions.

=== SOLUTION ===

  1. Removed all Derived Data in Xcode
  2. Performed a code clean (CMD + K)
  3. Fixed problematic code location (as Xcode indicated)

internal func swiftTask(task: BFTask) -> Task {
let taskCompletionSource = TaskCompletionSource()
task.continueWithBlock { task in
if task.cancelled {
taskCompletionSource.tryCancel()
} else if let error = task.error where task.faulted {
taskCompletionSource.trySet(error: error)
// taskCompletionSource.trySetError(error)
} else if let result = task.result {
taskCompletionSource.trySet(result: result)
// taskCompletionSource.trySetResult(result)
} else {
fatalError("Unknown task state")
}
return nil
}
return taskCompletionSource.task
}

Above is the location where taskCompletionSource has an incorrect method signature "trySetResult". This method no longer exists and it appears it has been combined into an overloaded, single method called "trySet".

By changing this to the code above taskCompletionSource.trySet(result: result), I was able to compile successfully.

parseObject method can't parse complex PFObjects

Hi @richardjrossiii , is it possible to improve parseObject<T: PFObject>(objectDictionary: [String:AnyObject]) method, so it correctly parses complex PFObjects? Currently it even leaves PFACL as a plain dictionary, which causes an error on saving the object later ([NSCFDictionary hasUnresolvedUser] unrecognized selector sent to instance)

I was thinking of using (instancetype)ACLWithDictionary:(NSDictionary *)dictionary method, but it seems marked as a private.

Is there a way to use a standard Parse iOS SDK for parsing the server's response to PFObject?

What's the "right" way of using liveQuery in ObjC project?

Hi, I've been having somewhat unique issue, since I can't find the answer here, so I think it's unique.
My project written in ObjC and using cocoa pods.
So.. like usual, I added liveQuery to Podfile, and pod install, my cocoa pods is 1.0.1.
Also I am using user_frameworks! in pod file, so building the project is fine.
So.. in objC header file, I user @import ParseLiveQuery; to import the framework, it looks fine, but if I add @import syntax on .m file, I got the error in screen shot.
Anyway, I imported the framework on header file and try to access the methods, but I can't access any of method of liveQuery. I am not sure I am doing things in right way, or I did forget something important here. I am kind of new to "mix and match" things, so your advice on me would be very helpful!

screen shot 2016-09-05 at 4 39 05 pm

Event handlers not called in Objective-c

Hello again :)

I have objective-c project, where i want to implement LiveQuery.

I tried almost everything but event handlers are not called. for example i add subscription handler to query it never gets called, but Client.swift gets message from server in handleOperationAsync.

{"op":"subscribed","clientId":2,"requestId":1}
PFQuery *query = [SEGame query];
[query whereKey:@"objectId" equalTo:@"rRB6Htb1S6"];
[[query subscribe] addSubscribeHandler:^(PFQuery * _Nonnull r) {
    NSLog(@"Subscribed");
}];

One more strange thing is that Client.swift never gets messages about .Create, .Delete, .Enter, .Leave, .Update

Maybe i am doing something wrong? Can you please provide objective-c example or just point me the right way to debug/fix this?

Is there a framework for iOS Swift (or Objective C)?

I'm using Swift as my primary language but I don't use cocoa pods. I was wondering if you could put up documentation on how to use Live Queries in my projects by using frameworks or some other way? Thanks.

LiveQuery doesn't receive any response in iOS ObjC

I have configured a parse-server running LiveQuery on Heroku with port 36318.

Below is my index.js and the ObjC code that I am using

index.js

var express = require('express');
var cors = require('cors'); // add this line below it

var ParseServer = require('parse-server').ParseServer;
var path = require('path');

var databaseUri = process.env.DATABASE_URI || process.env.MONGOLAB_URI;

if (!databaseUri) {
  console.log('DATABASE_URI not specified, falling back to localhost.');
}

var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || 'myAppId',
  masterKey: process.env.MASTER_KEY || 'myMasterKey', //Add your master key here. Keep it secret!
  serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',  // Don't forget to change to https if needed
javascriptKey: process.env.JAVASCRIPT_KEY || '',  //** add this line no need to set values, they will be overwritten by heroku config vars
restAPIKey: process.env.REST_API_KEY || '', //** add this line
dotNetKey: process.env.DOT_NET_KEY || '', //** add this line/Users/apple/Desktop/MyApp/Heroku/paidui
clientKey: process.env.CLIENT_KEY || '', //** add this line

  liveQuery: {
    classNames: ["Purchase"] // List of classes to support for query subscriptions
  }
});

var app = express();
app.use(cors()); // add this line below it


// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));

// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);

// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
  res.status(200).send('Make sure to star the parse-server repo on GitHub!');
});

// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
  res.sendFile(path.join(__dirname, '/public/test.html'));
});

var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
    console.log('parse-server-example running on port ' + port + '.');
});

// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);

viewcontroller

@import Parse;
@import ParseLiveQuery;
@import Parse.PFUser;
@import Parse.PFQuery;
@import UIKit;

@property (nonatomic, strong) PFLiveQueryClient *client;
@property (nonatomic, strong) PFQuery *query;
@property (nonatomic, strong) PFLiveQuerySubscription *subscription;


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    NSError *error = nil;
    PFUser *user = [PFUser logInWithUsername:@"test" password:@"test" error:&error];

    self.client = [[PFLiveQueryClient alloc] init];
    self.query = [[[Purchase query] whereKey:@"email" equalTo:@"[email protected]"] orderByAscending:@"createdAt"];


    [[self.query findObjectsInBackground] continueWithBlock:^id (BFTask *task) {

        for (Purchase *purchase in task.result) {
            NSLog(@"%@ %@",purchase.email, [purchase.months stringValue]);
        }

    }];

    self.subscription = [[self.client subscribeToQuery:self.query] addCreateHandler:^(PFQuery * query, PFObject * purchase) {
        NSLog(@"%@ %@",purchase.createdAt, purchase.objectId);
    }];

}

I can't receive events when I create a new Object for "Purchase" class.
Is there any mistake or something missing in the subscription process?

Thanks!

Update server log:

2016-06-03T11:46:52.808353+00:00 heroku[router]: at=info method=GET path="/LQ" host=testserver.herokuapp.com request_id=d4dc1baa-dc93-4c3d-9d24-2e1519a9dec0 fwd="42.72.125.227" dyno=web.1 connect=1ms service=55603ms status=101 bytes=220

status 101?

Include of non modular

I would like to try it. I create a podfile with :

pod 'ParseLiveQuery'

I have this error when I try to build it :
capture d ecran 2016-04-07 a 21 55 24

Thank you for you help

LiveQueryErrors.InvalidJSONError

Running latest versions of parse server and iOS SDK.

Server setup:

  liveQuery: {
    classNames: ["ChatRooms", "ChatMessages"]
  }

ChatRooms.swift

    let liveQueryClient = ParseLiveQuery.Client()
    private var subscription: Subscription<PChatRoom>?

    var chatRoomsQuery: PFQuery {
        if isPrivate {
            return (PChatRoom.query()?
                .whereKey("name", containsString: PUser.currentUser()?.objectId)
                .whereKey("private", equalTo: true)
                .whereKey("belongsToUser", equalTo: PUser.currentUser()!)
                .orderByDescending("createdAt"))!
        } else {
            return (PChatRoom.query()?
                .whereKey("isPrivate", equalTo: false)
                .orderByDescending("createdAt"))!
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        getExistingRooms()
        subscribeToUpdates()
    }

    func subscribeToUpdates() {
          subscription = liveQueryClient
            .subscribe(chatRoomsQuery)
            .handle(Event.Created) { _, room in
                self.addRoom(room)
        }
    }

    func getExistingRooms() {
        chatRoomsQuery.findObjectsInBackground().continueWithBlock() { task in
            if let chatRooms = task.result as? [PChatRoom] {
                for room in chatRooms {
                    self.arrayOfChatRooms.append(room)
                }
                self.tableView.reloadData()
            }
            return nil
        }
    }

Messages.swift

    let liveQueryClient = ParseLiveQuery.Client()
    private var subscription: Subscription<PChatMessage>?

    var chatQuery: PFQuery {
        if isPrivate {
            return (PChatMessage.query()?
                .whereKey("room", equalTo: room)
                .whereKey("private", equalTo: true)
                .whereKey("belongsToUser", equalTo: PUser.currentUser()!)
                .orderByDescending("createdAt"))!
        } else {
            return (PChatMessage.query()?
                .whereKey("isPrivate", equalTo: false)
                .whereKey("room", equalTo: room)
                .orderByDescending("createdAt"))!
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        getExistingMessages()
        subscribeToUpdates()
    }

    func getExistingMessages() {
        chatQuery.findObjectsInBackground().continueWithBlock() { task in
            if let chatLog = task.result as? [PChatMessage] {
                for message in chatLog {
                    self.addMessage(message.author.objectId!, text: message.message)
                }
                self.finishReceivingMessage()
            }
            return nil
        }
    }

    func subscribeToUpdates() {
        subscription = liveQueryClient
            .subscribe(chatQuery)
            .handle(Event.Created) { _, message in
                self.incomingMessage(message)
        }
    }

Nearly identical liveQueries in both classes.
ChatRooms.swift works fine and receives live updates.
When calling subscribe in Messages.swift, the console outputs only "140725914386528"
and breakpoints at throw LiveQueryErrors.InvalidJSONError(json: json, expectedKey: key) in Operation.swift

        func jsonValue<T>(json: [String:AnyObject], _ key: String) throws -> T {
            guard let value =  json[key] as? T
                else {
                    **throw LiveQueryErrors.InvalidJSONError(json: json, expectedKey: key)**
            }
            return value
        }

What might be causing this to be thrown?

tvOS support

What do we need to do in order to make this library support tvOS? Right now it doesn't compile when installed via cocoapods.

Errors!

After install ParseLiveQuery with cocoapods. I have error in BoltsHelper.swift - could not build objc module "Bolts" and another one error "Include of non-modular header inside framework module 'Bolts.BFCancellationToken'

Multiple subscriptions adds additional sends after socket opens?

I just tested how many times things are getting sent to the server by printing every time the sendOperationAsync function gets called like so.

func sendOperationAsync(operation: ClientOperation) -> Task<Void> {
        return Task(.Queue(queue)) {
            let jsonEncoded = operation.JSONObjectRepresentation
            let jsonData = try NSJSONSerialization.dataWithJSONObject(jsonEncoded, options: NSJSONWritingOptions(rawValue: 0))
            let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding)
            print("socket is sending jsonString")
            self.socket?.send(jsonString)
        }
    }

I am subscribing to 2 queries back-to-back and after the socket connects I am seeing 3 "socket is sending jsonString" printed. Does this mean that I am getting subscribed twice to one of my subscriptions?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.