Keep Data Equal

Asked

Viewed 240 times

3

I’m making a Chat on Android.

I’m using Servlet (with JSON) + Oracle + Android.

When I add a contact, for example, I save this contact in the Oracle database, via Servlet.

But, when it comes to displaying contacts in a ListView, if I search for this data via JSON server, it may be that, the user does not have internet and with that, he would not be able to see his contacts.

What would be the best solution for this?

Create a local bank and create a service that makes both banks equal?

I accept suggestions.

  • You can download your JSON and save it in a file even, have some applications that do this, such as Nubank.. But it has a detail... It will be possible to add a contact without internet?

  • I guess so, if it wouldn’t be too limited.

  • I think the quickest solution would be to use a local bank (Sqlite), but if you have to make too many records and the use of the two banks get too much work I think it’s best to find a more viable way out

  • @Luhhh, I edited my answer by adding another implementation. I use both forms in different systems here at the company where I work.

2 answers

8

Well, since it’s a question based on opinions, I’m going to expose my.

First of all I would make a local bank (Sqlite).

That bank would be a mirror of my remote bank.

To ensure greater data security and synchronization, I would create a background service every time the application is open.

That my service would do?

  1. Get a list of local contacts (Sqlite).
  2. Send this list to a web service.
  3. Upon receipt of the list, have an algorithm that scans all received contacts by comparing them with the already saved contacts.
  4. If there is difference of contacts, do what necessary to update both sides.
  5. In this case, I can have two situations: The local bank is larger than the remote one (which forces me to do a remote update). Or the remote bank is larger than the location. (which forces me to do a location update).

In any of these cases you will do the same thing: Synchronize the banks.

As you mentioned that you are working with Servlets, you can use the removeAll to compare two lists (the list of the local bank and the remote bank).

Collection listaRemota = new ArrayList() {{
    add("maca");
    add("laranja");
}};

Collection listaLocal = new ArrayList() {{
    add("maca");
    add("laranja");
    add("coco");
    add("morango");
}};

// Remover os elementos 
listaLocal.removeAll(listaRemota);

// Exibir resultado
System.out.println("Resultado: " + listaLocal);

Resultado: ["coco", "morango", "laranja"]

Remember that as your case is a comparison (complex or not) of objects. You will need to define a comparison rule (overload of the method equals()) to be able to use such a mechanism.

Another example of implementation

You can also stack all actions on top of any contact. This way you will always have the largest mass of data in your local database (Sqlite) and ensures synchronization every time the mobile device presents internet connectivity.

You can create a table of type:

CREATE TABLE sincronizacao (id INTEGER PRIMARY KEY, ENTIDADE varchar(20), ACAO varchar(1), VALOR varchar(500), SINCRONIZADO INTEGER, DATA_SINCRONIZAR INTEGER);

You can make a generic method in each action taken upon a contact (INSERT,UPDATE,DELETE) which will record exactly the "status" - or value - of the contact:

insert into sincronizacao (entidade, acao, valor, sincronizado, data_sincronizar) values ('CONTATO', 'I', '{  "telefones": [    "(21) 91111-2222",    "(21) 92477-1515"  ],  "nome": "Stack Overflow PT",  "null": null,  "endereco": "Brasil",  "object": {    "a": "b",    "c": "d",    "e": "f"  },  "outra_propriedade": "Olá, mundo!"}', 0, CURRENT_TIMESTAMP)

The above value is a JSON, meaning you can do serialization and deserialization on any of the "sides":

{
  "telefones": [
    "(21) 91111-2222",
    "(21) 92477-1515"
  ],
  "nome": "Stack Overflow PT",
  "null": null,
  "endereco": "Brasil",
  "object": {
    "a": "b",
    "c": "d",
    "e": "f"
  },
  "outra_propriedade": "Olá, mundo!"
}

Then I make a change in some property of that same contact and make another record in my table:

insert into sincronizacao (entidade, acao, valor, sincronizado, data_sincronizar) values ('CONTATO', 'U', '{  "telefones": [    "(21) 91111-2222",    "(21) 92477-1515"  ],  "nome": "Stack Overflow PT",  "null": null,  "endereco": "Brasil",  "object": {    "a": "b",    "c": "d",    "e": "f"  },  "outra_propriedade": "Olá, mundo! Essa propriedade foi alterada."}', 0, CURRENT_TIMESTAMP)

VALOR in the view "familiar":

{
  "telefones": [
    "(21) 91111-2222",
    "(21) 92477-1515"
  ],
  "nome": "Stack Overflow PT",
  "null": null,
  "endereco": "Brasil",
  "object": {
    "a": "b",
    "c": "d",
    "e": "f"
  },
  "outra_propriedade": "Olá, mundo! Essa propriedade foi alterada."
}

You can also create a Trigger do that.

Anyway at the end of the day you’ll do the same thing:

Get a list of unrealized synchronizations:

select * from sincronizacao where sincronizado = 0;

Send a list of objects (after deserializing them) to a webservice. In the webservice, it follows the same treatment flow in the ascending order of the data_sincronizar.

In the case above, notice that first I did an action "I" (insert) and then did another action "U" (update). In the list handling on the webservice side, I will perform the actions according to the order they were "created". So on my remote server, I would first do a insert of the unserialized object. And soon afterwards would make a update.

Returning an "OK" from the webservice, you "scan" the same mailed list and update your control column sincronizado:

update sincronizacao set sincronizado = 1 where id in (string_delimitada_por_virgula_com_cada_id_atualizado_no_ws);

And just like that!

This way you also always guarantee the local update (which is more important in your case) and also guarantee the synchronization and security of this data by storing the information on a remote server, since, for use of chat, it is necessary to connect to the internet.

2

Prioritize saving data locally instead of saving it to an external server.

The reasons are in the question itself. If there is no internet connection, you won’t even be able to add a new contact or simple actions like editing an existing contact, deleting, etc.

I suggest you save locally and create options to "export" to an external medium, which can be a txt (csv) file, bluetooth upload, database, etc.

That’s even what all apps of the kind do.

I believe there is no need to show codes because doubt seems to be only conceptual.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.