Skip to content

LiveQuery not sending events #444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
el-mail opened this issue Jun 15, 2017 · 9 comments
Closed

LiveQuery not sending events #444

el-mail opened this issue Jun 15, 2017 · 9 comments

Comments

@el-mail
Copy link

el-mail commented Jun 15, 2017

Aloha!
i use LiveQuery in Parse JS SDK v1.9.2
LiveQueryServer running, but does not trigger LiveQuery event.
event 'create', 'update' and other does't work
example code

 var ClassObject = Parse.Object.extend(classname);
    var query = new Parse.Query(ClassObject);
    var subscription = query.subscribe();

    subscription.on('open', function(){
      console.log('open'); // open
    });
    subscription.on('create', function(obj){
      console.log('create', obj.attributes); // not working
    });
    subscription.on('update', function(obj){
      console.log('update', obj.attributes); //and here not working
      document.getElementById("json").innerHTML = JSON.stringify(obj.attributes, undefined, 2);
    });

Log on server

verbose: Request: {"op":"connect","applicationId":"","javascriptKey":""}
1|parse-wr | info: Create new client: 1
1|parse-wr | verbose: Push Response : "{\"op\":\"connected\",\"clientId\":1}"
1|parse-wr | verbose: Request: {"op":"subscribe","requestId":1,"query":{"className":"Map","where":{}}}
1|parse-wr | verbose: Push Response : "{\"op\":\"subscribed\",\"clientId\":1,\"requestId\":1}"
1|parse-wr | verbose: Create client 1 new subscription: 1
1|parse-wr | verbose: Current client number: 1

server index.js setting

'use strict'

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

const databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;

const api = new ParseServer({  
    databaseURI: databaseUri || 'mongodb://',
    cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
    appId: process.env.APP_ID || '',
    masterKey: process.env.MASTER_KEY || '',
    clientKey: process.env.CLIENT_KEY || '',
    javascriptKey: process.env.JAVASCRIPT_KEY || '',
    restAPIKey: process.env.REST_API_KEY || '',
    serverURL: process.env.SERVER_URL || 'http://localhost:1337/v2'
    verbose: true,
    liveQuery: {
        classNames: ['_User', 'Map'],
        redisURL: 'redis://localhost:6379'  
    }
});

let app = express();


app.use('/public', express.static(path.join(__dirname, '/public')));


const mountPath = process.env.PARSE_MOUNT || '/v2';
app.use(mountPath, api);


app.get('/', (req, res) => {
    res.status(200).send('api');
});

const port = process.env.PORT || 1337;
let httpServer = require('http').createServer(app);
httpServer.listen(port, () => {
    console.log(' v2.0 running on port ' + port + '.');
});
let parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer,  {
  appId: 'key',
  masterKey: 'key',
  keyPairs: {
    "restAPIKey": "key",
    "javascriptKey": "key",
    "clientKey": "key",
    "masterKey": "key"
  },
  serverURL: 'http://localhost:1337/v2',
  websocketTimeout: 10 * 1000,
  cacheTimeout: 60 * 600 * 1000,
  logLevel: 'VERBOSE',    
  redisURL: 'redis://localhost:6379'
});

Environment Setup
Server
parse-server version: 2.4.2

Database
MongoDB version: 3.2.13

@kkgelu
Copy link

kkgelu commented Jun 20, 2017

Have you tried to put constraints on the query?
According to https://github.com/parse-community/parse-server/wiki/Parse-LiveQuery-Protocol-Specification : constraints or query.where are mandatory.

My experience is not all constraints are supported, I had an inner query which didn't work.

@Ernesto89
Copy link

Ernesto89 commented May 8, 2018

So I followed the steps and created 2 Heroku Apps, one for the Parse Server and another for the LiveQuery Server following the schema for scalability. It subscribed to the query (Using Swift Client) but the events handler wasn't being called when I changed or created the object. So i tried initializing the LiveQuery Server on the Parse Server, now it works but I'm not sure which Heroku App is running the LiveQuery processes. This is how I configured them:

Parse Server (Heroku App 1):

var api = new ParseServer({
  databaseURI: databaseUri
  cloud: process.env.CLOUD_CODE_MAIN ,
  appId: process.env.APP_ID,
  masterKey: process.env.MASTER_KEY,
  serverURL: process.env.SERVER_URL,
  fileKey: process.env.FILE_KEY,
  javascriptKey: process.env.JAVASCRIPT_KEY,
  clientKey: process.env.CLIENT_KEY,
  liveQuery: {
    classNames: ['MsgTest','Message'],
    redisURL: process.env.REDIS_URL
  });

var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer, {
  appId: process.env.APP_ID_LIVE,
  masterKey: process.env.MASTER_KEY_LIVE,
  serverURL: process.env.SERVER_URL_LIVE,
  keyPairs: {
    "javascriptKey": process.env.JAVASCRIPT_KEY_LIVE,
    "clientKey": process.env.CLIENT_KEY_LIVE
  },
  websocketTimeout: 10 * 1000,
  cacheTimeout: 60 * 600 * 1000,
  logLevel: 'VERBOSE',
  redisURL: process.env.REDIS_URL
});

LiveQuery Server (Heroku App 2):

var api = new ParseServer({
  databaseURI: databaseUri,
  appId: process.env.APP_ID_LIVE,
  masterKey: process.env.MASTER_KEY_LIVE,
  serverURL:process.env.SERVER_URL_LIVE,
  clientKey: process.env.CLIENT_KEY_LIVE,
  liveQuery: {
    classNames: ['MsgTest','Message'],
  }
});

var parseLiveQueryServer = ParseServer.createLiveQueryServer(httpServer, {
  appId: process.env.APP_ID_LIVE,
  masterKey: process.env.MASTER_KEY_LIVE,
  serverURL: process.env.SERVER_URL_LIVE,
  keyPairs: {
    "javascriptKey": process.env.JAVASCRIPT_KEY_LIVE,
    "clientKey": process.env.CLIENT_KEY_LIVE
  },
  websocketTimeout: 10 * 1000,
  cacheTimeout: 60 * 600 * 1000,
  logLevel: 'VERBOSE',
  redisURL: process.env.REDIS_URL,
});

**Client (Swift): **

self.theQuery = Message.query()?.whereKey("Test", equalTo: true)
self.subscriber = Client(server: ws://process.env.SERVER_URL_LIVE , applicationId: process.env.APP_ID_LIVE, clientKey: process.env.CLIENT_KEY_LIVE
self.subscription = subscriber.subscribe(theQuery)
self.subscription.handle(Event.created, { (query, object) in
print("Item Created")
})

In the logs, the LiveQuery Server shows the connection and it "works", but in the Parse Server logs it shows a process as well and the Redis Activity is double what it is supposed to be.

Any help, comment is greatly appreciated!!! Thanks in advanced!

@Marcel-Malus
Copy link

Hi,
I have the same problem like you described in the first post. Using newest Parse JS SDK 1.11.1 and also newest Parse Server (from parse-server-example) running on Heroku (free account).
According to the logs (client and server logs) my client subscribes successfully. I also added

Parse.LiveQuery.on('open', () => {
    console.log('socket connection established');
  });

which confirms, that the connection is established.
I also added a simple equalTo constraint on the query.
But nothing works. I don't get any update or create events. According to the server logs none are send.
@Ernesto89 you say in your latest post that your setup now "works". Is this still the case? What do you mean with the "...", what does not work or what is the problem with your setup?

Appreciate any help! Also can anyone confirm, that the setup works with heroku ect.?
Thank you!

@Ernesto89
Copy link

@Receks Yes it works. What I meant is that I managed to set up the Livequery in the standard Parse Server (Used Parse Server example in heroku as well), but not in the scalable way suggested in the docs (creating 2 instances or apps in heroku, one for the parse server and another for the livequery server).

I was using Swift client but it should word as well with the ParseJS SDK, if you elaborate on your code maybe I can help you out on why is not getting the updates on the events.

@Marcel-Malus
Copy link

Marcel-Malus commented Jun 9, 2018

Alright, gladly. This ist my index.js:

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

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

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

var api = new ParseServer({
	//**** General Settings ****//

	databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
	cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
	serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',  // Don't forget to change to https if needed

	//**** Security Settings ****//
	//allowClientClassCreation: process.env.CLIENT_CLASS_CREATION || false, 
	appId: process.env.APP_ID || 'myAppId',
	masterKey: process.env.MASTER_KEY || 'myMasterKey', //Add your master key here. Keep it secret!	
	
	//**** Live Query ****//
	LiveQuery: {
	 	// List of classes to support for query subscriptions (expensive)
	 	classNames: ['TestObject', 'ChatMessage'] 
	},
	
	//**** File Storage ****//
	filesAdapter: new S3Adapter(
		{
			directAccess: true
		}
	)
});

var app = express();

// 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('I dream of being a website.  Please 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, {
	appId: process.env.APP_ID || 'myAppId',
	masterKey: process.env.MASTER_KEY || 'myMasterKey',
	serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',
	websocketTimeout: 10 * 1000,
	cacheTimeout: 60 * 600 * 1000,
	logLevel: 'VERBOSE'
});

And here the relevant client code:

Parse.initialize("...");
Parse.serverURL = 'https://.../parse';

var MESSAGES = [];
var ChatMessage = Parse.Object.extend("ChatMessage");
var QUERY = new Parse.Query("ChatMessage");

var QUERY_SUBSCR = new Parse.Query("ChatMessage");
QUERY_SUBSCR.equalTo("name", "myName");
var subscription = QUERY_SUBSCR.subscribe();

function renderMessages() {
	// This renders the full list of messages to the screen
	...
}

function loadMessages(data) {
	// Load all the old messages from parse, newest first
	QUERY.descending("createdAt");
	QUERY.find().then(function(results) {
		MESSAGES = results;
		renderMessages();
	});
}

function sendMessage(data) {
	// Save a chat message to parse and then render it on the screen
	var message = new ChatMessage();
	message.set("name", data.name);
	message.set("content", data.content);
	message.save().then(function(obj) {
		console.log("Message saved!");
		// addMessage(obj)
	}, function(err) {
		alert(err.message);
	});
}

function addMessage(message) {
	console.log("Adding chat message the front of the messsages list");
	MESSAGES.unshift(message);
	renderMessages();
}


function subscribeMessages(message) {
	console.log("Subscribing to new messages from parse");

	subscription.on("create", function(message) {
		console.log("Message created");
		addMessage(message);
	});
  
  Parse.LiveQuery.on('open', () => {
    console.log('socket connection established');
  });
  Parse.LiveQuery.on('close', () => {
    console.log('socket connection closed');
  });
  Parse.LiveQuery.on('error', (error) => {
    console.log(error);
  });
}

$(document).ready(function() {

	// Load all the existing messages for this room
	loadMessages();

	// Listen for new messages
	subscribeMessages();

	// Handle when the user wants to send a message
	var chatForm = $("#chat-form");
	chatForm.submit(function(e) {

		e.preventDefault();
		var data = {};
		chatForm.serializeArray().map(function(x){data[x.name] = x.value;});
		sendMessage(data);
		$("#message").val("");
	});
});

When starting I see this console outputs:
"Subscribing to new messages from parse"
"socket connection established"
When creating new messages with the Name matching the subscribe query I see just this:
"Message saved!"
But not as expected also:
"Message created" from the subscribed function.
When reloading the app I then see the full List of message (with the new one as well, which is not visible before).

But my assumption is, that it is a server side issue. According to this: https://github.com/parse-community/parse-server/wiki/Parse-LiveQuery-Protocol-Specification I would expect a "create Event" in the server logs (as soon as a ChatMessage is created), but which I is not there. The subscribe Events are shown in the server logs.

@Ernesto89 are you still using Parse JS SDK v1.9.2? Maybe this is an issue with the newest parse server Version.

@Moumouls
Copy link
Member

Probably fixed by this : Parse Server Role Limitation

@stale
Copy link

stale bot commented Feb 5, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Feb 5, 2019
@stale stale bot closed this as completed Feb 12, 2019
@rsmets
Copy link

rsmets commented Jan 27, 2020

@Receks I know it's been a while but curiouis if you were ever able to solve this? Currently running into the same issue. No create event by the main app so nothing over the redis wire to the LQ server.

@dplewis
Copy link
Member

dplewis commented Jan 31, 2020

@rsmets Can you open a separate issue and fill out the template?

@dplewis dplewis removed the stale label Oct 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants