Hi,
I have configured the "geofence notification" such as only send the notifications to those users who have created them. So it is working fine for all the devices but when I add new device so for this device the old geofences are not working properly like "geofenceEnter" and "geofenceExit". And I have checked that geofence is already linked with the user and device both.
And there is not showing any kind of error in the log file. I am not getting to detect where I am doing wrong thing.
I have added this syntax in the file:
/database>NotificationManager.java>updateEvent(){}> after dataManager.add(event);
CustomUtilities.sendNotification(event.getDeviceId(), event.getType(), position, event);
:/custom>CustomUtilities.java
package org.traccar.custom;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonReader;
import org.traccar.Context;
import org.traccar.database.NotificationManager;
import org.traccar.model.Alert;
import org.traccar.model.Device;
import org.traccar.model.Event;
import org.traccar.model.FirebaseToken;
import org.traccar.model.Geofence;
import org.traccar.model.Position;
public class CustomUtilities {
public static final String ALERT = "alert";
public static void sendNotification(long deviceId, String eventType, Position position, Event event) {
try {
Device device = Context.getDataManager().getDevice(deviceId);
Collection<FirebaseToken> tokens;
if(eventType.equals(Event.TYPE_GEOFENCE_ENTER) || eventType.equals(Event.TYPE_GEOFENCE_EXIT)){
tokens = Context.getDataManager().selectFirebaseTokenByUserGeofence(event.getGeofenceId());
}
else{
tokens = Context.getDataManager().selectRegisteredClients(device.getId());
}
if(tokens.size()>0){
String[] gcm_tokens = new String[tokens.size()];
ArrayList<Long> users = new ArrayList<>();
if (position != null && (position.getAddress() == null || position.getAddress().isEmpty())) {
position.setAddress(GoogleMaps.getAddress(position));
}
Iterator<FirebaseToken> iterator = tokens.iterator();
int index = 0;
while (iterator.hasNext()) {
FirebaseToken token = iterator.next();
gcm_tokens[index++] = token.getFirebase_token();
if (!users.contains(token.getUser_id())) {
users.add(token.getUser_id());
}
}
Alert alert = new Alert();
alert.setDevice_id(deviceId);
alert.setCategory(eventType);
alert.setPosition(position);
if (gcm_tokens.length > 0) {
Collection<Geofence> matches = null;
String time_string = new SimpleDateFormat("hh:mm:ss a dd MMM").format(position.getDeviceTime());
switch (eventType) {
case Event.TYPE_GEOFENCE_ENTER:
matches = Context.getDataManager().selectGeofence(event.getGeofenceId());
if (matches.size() > 0) {
Geofence geofence = matches.iterator().next();
alert.setType(ALERT);
alert.setCategory(Position.ALARM_GEOFENCE_ENTER);
alert.setText(device.getName() + " entered " + geofence.getName() + " at " + time_string);
}
break;
case Event.TYPE_GEOFENCE_EXIT:
matches = Context.getDataManager().selectGeofence(event.getGeofenceId());
if (matches.size() > 0) {
Geofence geofence = matches.iterator().next();
alert.setType(ALERT);
alert.setCategory(Position.ALARM_GEOFENCE_EXIT);
alert.setText(device.getName() + " left " + geofence.getName() + " at " + time_string);
}
break;
}
if (alert.getType() != null && !alert.getType().isEmpty()) {
for (Long user : users) {
alert.setUserId(user);
Context.getDataManager().addAlert(alert);
}
ServerConnection.sendAlert(alert, gcm_tokens);
}
}
}
} catch (SQLException | IOException ex) {
Logger.getLogger(NotificationManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
WHERE
a) selectFirebaseTokenByUserGeofence(event.getGeofenceId());
<entry key='database.selectTokensByUserGeofence'>
SELECT * FROM firebase_token where user_id in ( select userid from user_geofence where geofenceid=:geofenceId )
</entry>
b) selectRegisteredClients(device.getId());
<entry key='database.selectRegisteredClients'>
SELECT * FROM firebase_token WHERE user_id in (select userId from user_device where deviceId=:deviceId)
</entry>
Please help me to find my error and it is not working only for one device and for the rest of the devices are working
Sorry, I didnt read properly your question. Please dismiss my comments.
What does your custom notificator does that is not in latest official version?
Actually, it is based on mobile or web system notification by FCM.
Ernesto Vallejo, this is just only for my use case.
Problem is solved now. I just upload the build by two times. First time it did not work but second time it worked.
Hi Anton,
I have found something in creating Geofence Events. Here is the log-
A vehicle is entered into the geofence at 2019-03-15 09:03:00(position id: 24127900) with the server receiving time 2019-03-15 09:03:00 which is correct.
But it generates again geofenceEnter at 2019-03-15 10:58:08(position id: 24142379) with the server receiving time 2019-03-15 18:06:03.
And the vehicle is exited from the geofence at 2019-03-15 18:04:19(position id: 24201633) with the server receiving time 2019-03-15 18:04:19.
And rest of the positions data between position ids from 24142379 to 24201581 are invalid.
So I want to know why geofenceEnter event happened again without geofenceExit. And if this is not the problem, then what it can be scenarios for this event.
Actually this same thing was happened with another device too and the case was same. How can I solve this? Please reply.
Hi,
I have configured the "geofence notification" such as only send the notifications to those users who have created them. So it is working fine for all the devices but when I add new device so for this device the old geofences are not working properly like "geofenceEnter" and "geofenceExit". And I have checked that geofence is already linked with the user and device both.
And there is not showing any kind of error in the log file. I am not getting to detect where I am doing wrong thing.
I have added this syntax in the file:
/database>NotificationManager.java>updateEvent(){}> after dataManager.add(event);
:/custom>CustomUtilities.java
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.traccar.custom; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonReader; import org.traccar.Context; import org.traccar.database.NotificationManager; import org.traccar.model.Alert; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.FirebaseToken; import org.traccar.model.Geofence; import org.traccar.model.Position; /** * * @author Sumit */ public class CustomUtilities { public static final String ALERT = "alert"; public static void sendNotification(long deviceId, String eventType, Position position, Event event) { try { Device device = Context.getDataManager().getDevice(deviceId); Collection<FirebaseToken> tokens; if(eventType.equals(Event.TYPE_GEOFENCE_ENTER) || eventType.equals(Event.TYPE_GEOFENCE_EXIT)){ tokens = Context.getDataManager().selectFirebaseTokenByUserGeofence(event.getGeofenceId()); } else{ tokens = Context.getDataManager().selectRegisteredClients(device.getId()); } if(tokens.size()>0){ String[] gcm_tokens = new String[tokens.size()]; ArrayList<Long> users = new ArrayList<>(); if (position != null && (position.getAddress() == null || position.getAddress().isEmpty())) { position.setAddress(GoogleMaps.getAddress(position)); } Iterator<FirebaseToken> iterator = tokens.iterator(); int index = 0; while (iterator.hasNext()) { FirebaseToken token = iterator.next(); gcm_tokens[index++] = token.getFirebase_token(); if (!users.contains(token.getUser_id())) { users.add(token.getUser_id()); } } Alert alert = new Alert(); alert.setDevice_id(deviceId); alert.setCategory(eventType); alert.setPosition(position); if (gcm_tokens.length > 0) { Collection<Geofence> matches = null; String time_string = new SimpleDateFormat("hh:mm:ss a dd MMM").format(position.getDeviceTime()); switch (eventType) { case Event.TYPE_GEOFENCE_ENTER: matches = Context.getDataManager().selectGeofence(event.getGeofenceId()); if (matches.size() > 0) { Geofence geofence = matches.iterator().next(); alert.setType(ALERT); alert.setCategory(Position.ALARM_GEOFENCE_ENTER); alert.setText(device.getName() + " entered " + geofence.getName() + " at " + time_string); } break; case Event.TYPE_GEOFENCE_EXIT: matches = Context.getDataManager().selectGeofence(event.getGeofenceId()); if (matches.size() > 0) { Geofence geofence = matches.iterator().next(); alert.setType(ALERT); alert.setCategory(Position.ALARM_GEOFENCE_EXIT); alert.setText(device.getName() + " left " + geofence.getName() + " at " + time_string); } break; } if (alert.getType() != null && !alert.getType().isEmpty()) { // Add Notification to the server for (Long user : users) { alert.setUserId(user); Context.getDataManager().addAlert(alert); } // Send Notification to the mobile devices ServerConnection.sendAlert(alert, gcm_tokens); } } } } catch (SQLException | IOException ex) { Logger.getLogger(NotificationManager.class.getName()).log(Level.SEVERE, null, ex); } } }
WHERE
a) selectFirebaseTokenByUserGeofence(event.getGeofenceId());
<entry key='database.selectTokensByUserGeofence'> SELECT * FROM firebase_token where user_id in ( select userid from user_geofence where geofenceid=:geofenceId ) </entry>
b) selectRegisteredClients(device.getId());
<entry key='database.selectRegisteredClients'> SELECT * FROM firebase_token WHERE user_id in (select userId from user_device where deviceId=:deviceId) </entry>
Please help me to find my error and it is not working only for one device and for the rest of the devices are working