UI not updating after deleting one element from array list - android

I am writing a chat application. On click of a button I am trying to remove selected friend from list And its working properly but on removing the friend the UI is not getting updated
private void removeFriend(String remfri) {
removefri = remfri;
{
try {
Constants.connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.accept_all);
Constants.connection.getRoster().createEntry(removefri, removefri, null);
Collection<RosterEntry> entries = Constants.connection.getRoster().getEntries();
for (RosterEntry entry : entries)
{
System.out.println("name..."+entry.getUser()+"...type.."+entry.getType());
if(entry.getType()==ItemType.none)
{
Presence unsubscribe = new Presence(Presence.Type.unsubscribe);
unsubscribe.setTo(removefri);
Constants.connection.sendPacket(unsubscribe);
// usersList.clear();
usersList.remove(removefri);
Log.d("removed"," the best friend " + removefri);
Pasting code for refrence :http://pastie.org/8744959

Use adapter.notifyDataSetChanged(); after removal

Related

How to query users collection using array of IDs from group collection

I have a collection where I store user groups. Each group has a group name, group limit and an array of users ID's.
I wonder how the best way to retrieve one group details and then users details, like name, photo, etc.
Right now, I am doing two queries to the database. First retrieving the group data(name, etc), second getting a list of users who has in the user details the information of the group ID:
"syncDesp = a4sQ27xb1wuD2rhONU2K"
I'm afraid of calling the database to many times.
// Get Group details
Preferencias prefs = new Preferencias(view.getContext());
listenGroups = pFirestore.collection("syncDesps").document(prefs.getSyncDesp()).addSnapshotListener((documentSnapshot, e) -> {
if(e != null){
Log.i("dados erro", Objects.requireNonNull(e).getMessage());
}
if(documentSnapshot != null){
String nomeGrupo = Objects.requireNonNull(documentSnapshot.get("nomeGrupo")).toString();
textNomeGrupo.setText(nomeGrupo);
ArrayList membrosGrupo = (ArrayList) Objects.requireNonNull(documentSnapshot.get("syncDesp"));
}
});
// Get User Details
FirebaseFirestore grupoFire = FirebaseFirestore.getInstance();
grupoFire.collection("usuarios")
.whereEqualTo("syncDesp", prefs.getSyncDesp())
.addSnapshotListener((queryDocumentSnapshots, e1) -> {
listaUsuarios.clear();
if(e != null){
Log.i("dados erro", Objects.requireNonNull(e1).getMessage());
}
for(DocumentSnapshot usuarioSnapshot : Objects.requireNonNull(queryDocumentSnapshots).getDocuments()){
String idU = (usuarioSnapshot.get("id") == null) ? "" : Objects.requireNonNull(usuarioSnapshot.get("id")).toString();
String nomeUsuario = (usuarioSnapshot.get("nome") == null) ? "" : Objects.requireNonNull(usuarioSnapshot.get("nome")).toString();
String fotoUsuario = (usuarioSnapshot.get("imgUsuario") == null) ? "" : Objects.requireNonNull(usuarioSnapshot.get("imgUsuario")).toString();
UsuarioMeuGrupo usuarioMeuGrupo = new UsuarioMeuGrupo();//
usuarioMeuGrupo.setIdUsuario(idU);
usuarioMeuGrupo.setNome(nomeUsuario);
usuarioMeuGrupo.setFoto(fotoUsuario);
listaUsuarios.add(usuarioMeuGrupo);
}
adaptera.setOnItemClickRemoverListener(uMeuGrupo -> {
Log.i("dados uMeuGrupo Clic", uMeuGrupo.getNome());
});
adaptera.notifyDataSetChanged();
});
I wonder if I should query the group collection separately from the users collection or if there is a way of making only one function to retrieve data from both collections.
It's not possible to make a single query in Cloud Firestore span multiple collections. There is no join-like operation like you have in SQL. The only exception to this is collection group queries, which doesn't apply to your situation.
What you're doing right now is probably the best you can do with the database structure you have. If you want fewer queries, you'll have to do something to restructure your data to support that.

Adding documents via batch write vs manually adding from console (possible firestore bug?)

I created a CSV to Firestore exporter and have every fields the exact same as required by my app to read the data and populate it on a recycler.
After exporting successfully, and the fields look the same to me, the entries does not appear on the recycler.
I used batch write and the entries appear all nice and well on console.
However, if I add 1 entry manually onto the same collection, that entry will appear immediately on the recycler!
Would this be a Firestore bug? Have anyone encountered this before?
Edit - the batch write codes:
try {
InputStream inputStream = getContentResolver().openInputStream(selectedfile);
final CSVReader reader = new CSVReader(new InputStreamReader(inputStream));
String [] nextLine;
String column1 ="", column2="", column3="", column4 = "";
Integer count=0;
FirebaseFirestore fs = FirebaseFirestore.getInstance();
FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
.setTimestampsInSnapshotsEnabled(true)
.build();
fs.setFirestoreSettings(settings);
WriteBatch batch = fs.batch();
while ((nextLine = reader.readNext()) != null) {
if (count > 0) {
DocumentReference productList = fs
.collection("ProductList")
.document("VendorA")
.collection("Items")
.document(nextLine[0]);
Map<String, Object> data = new HashMap<>();
data.put(column1, nextLine[0]);
data.put(column2, nextLine[1]);
data.put(column3, nextLine[2]);
data.put(column4, nextLine[3]);
batch.set(productList, data);
count++;
} else {
//first line of CSV file are the headers
column1 = nextLine[0];
column2 = nextLine[1];
column3 = nextLine[2];
column4 = nextLine[3];
count++;
}
}
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
mStatusUpdate.setText(getString(R.string.statusupdate, reader.getLinesRead() - 1));
mVendorName.setText("");
}
});
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
Edit #2:
I think I found the issue. Look at the attached picture. I just reported this to Firebase Support as well.
I added another same field with "Name" from the Firebase Console.
I'm not sure why Firestore is allowing a duplicate field here. They look exactly the same, I can't find any typo on both the fields.
Screen shot here: https://imgur.com/a/h8zVrX5
After I added the duplicate "Name", my app works fine!
This is the normal behaviour. When you are saying that will appear immediately, it means that you already have added a listener on that collection reference and start listening for changes. Cloud Firestore is a realitime database so when you are using a listener, every CRUD operation that you doind in your database will be visibile in your RecyclerView.
But note, this is not a bug, is the most important features of Cloud Firestore.

adding user in roster list isn't working

I am creating an simple one to one chat app, I've done with the message send and receive. Now I am trying to show the status of the user to another(contacts) like "online/offline" etc. For that I have to use Presence and Roster.But I don't know where and how to use that, I mean the complete flow of subscription request and accept and after the subscription, the status of the users i.e. Online/Offline etc.
First of all you need to send and accept contact request
From Open-fire you can also do it from back-end
Steps :
First click on Users/Groups >> click on "UserName" >> click on roster >> add roster
Here i attach screen of steps
click on add new item
add roster
edit roster and select subscription both
then after you will get roster list using this code
ArrayList<RosterEntry> rosterLists = new ArrayList<>();
public List<RosterEntry> getFriendsList() throws SmackException.NotLoggedInException, InterruptedException, SmackException.NotConnectedException {
rosterLists = new ArrayList<>();
roster = Roster.getInstanceFor(Config.conn1);//connection object of AbstractXMPPConnection
if (!roster.isLoaded()) {
roster.reloadAndWait();
Log.e("Roster :", "Reload and wait");
}
Collection<RosterEntry> entries = roster.getEntries();
Log.e("Size of Roster :", entries.size() + "");
for (RosterEntry entry : entries) {
rosterLists.add(entry);
Log.d("Buddies", "Here: " + entry.toString());
Log.d("Buddies", "User: " + entry.getUser());//get userinfo
Log.d("Buddies", "User Name:" + entry.getName());//get username
Log.d("Buddies", "User Status: " + entry.getStatus());//get status of user
}
listAdapter = new FriendUserListAdapter(UserListActivity.this, rosterLists);
user_list.setAdapter(listAdapter);
return rosterLists;
}
what is the difference between subscription type both and from???
When any user add bot has his/her contact, then in the end of whole process, subscription status of ofRoster(openfire) table is set to ‘from’. The desired result of this process is ‘both’

Issue in editing buddy display name using smack api android

Hi I am using smack api to build a chat application in android. I am displaying all my buddy list names in a page. I need to edit the buddy name of a particular buddy. When I long press a purticular buddy, I am displaying a new screen where there is an EditText to enter the new name and when an edit button is there. When I press the edit button I am calling the following button to edit the buddy name.
public boolean editName(String jid, String name) {
try {
RosterPacket packet = new RosterPacket();
packet.setType(IQ.Type.SET);
RosterPacket.Item item = new RosterPacket.Item(jid, name);
packet.addRosterItem(item);
connection.sendPacket(packet);
return true;
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
Then the edit page is closed and the buddy list is refreshed. But the new name is not reflected unless i relogin to the application.
I am loading the buddy list using the following code:
public static Collection<RosterEntry> entries = roster.getEntries();
for (RosterEntry entry : entries) {
Log.i("XMPPChat", "Name: " + entry.getName());
}
Can anybody tell me the reason?

Displaying Country and its calling code, but returning its Abbreviated code using Android XML

I am trying to develop a Registration screen from Android XML. As in every Registration form, I would need to display the list of countries. I am able to do this using string-array in strings.xml file.
The greater part of the problem is, when a user selects a country, the phone number field just below it should be initially filled with its respective country code, which may or may not be editable. Here, my problem is how do I get the country code when the country is selected. Do I need to use a database or is it achievable using xml itself?
Besides that, when user submits the Register form, I would have to send the abbreviated code of the country, not the full country name. Now, again this would require either a database or xml?
My app doesn't use database till now, it would not be so good to use database for this purpose. Moreover, almost any application that uses a registration needs this thing to be done, but I cannot find any resources on how to do this in Android.
Also, I would like to tell you that my minimum sdk is version 7.
Please help.
I was finally able to do it without using database. I'm writing down the steps so that it may help anyone else who needs the same thing to be done.
First I downloaded the CSV available at: https://github.com/mledoze/countries/blob/master/countries.csv
I removed all other fields, except those I needed. It left me with 3 fields: name, abbreviation and calling code.
Next, I downloaded the CSVReader from: http://code.google.com/p/secrets-for-android/source/browse/trunk/src/au/com/bytecode/opencsv/CSVReader.java
Got the items from the CSV as mentioned in How to parse the CSV file in android application? by "Kopfgeldjaeger" as:
String next[] = {};
List<String[]> list = new ArrayList<String[]>();
try {
CSVReader reader = new CSVReader(new InputStreamReader(getAssets().open("countries.csv")));
for(;;) {
next = reader.readNext();
if(next != null) {
list.add(next);
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
Next I added an ArrayList for each of the values like:
ArrayList<String> countryNames = new ArrayList<String>();
ArrayList<String> countryAbber = new ArrayList<String>();
ArrayList<String> countryCodes = new ArrayList<String>();
for(int i=0; i < list.size(); i++)
{
countryNames.add(list.get(i)[0]); // gets name
countryAbber.add(list.get(i)[1]); // gets abbreviation
countryCodes.add(list.get(i)[2]); // gets calling code
}
Then added it to the spinner in the XML layout as:
ArrayAdapter<String> countryAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, countryNames);
spinner.setAdapter(countryAdapter);
// adding event to display codes when country is selected
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int pos, long arg3) {
// display the corresponding country code
TextView tvCountryCode = (TextView) findViewById(R.id.country_code);
tvCountryCode.setText("+"+list.get(pos)[2]);
countryPosition = pos;
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
This way, I was able to display country code in the xml file, when a country was selected from the dropdown list.
Remember to add the setOnItemSelectedListener() to achive that.
I hope this helps somebody in future.
I would advise you to use a database. API level 7 supports SQLite databases (I used them in android 2.1 myself). Create one table that has all the required info:
create table countries (
_id integer primary key autoincrement,
country_code char(2),
country_name varchar,
phone_code char(4),
editable integer
);
Then store your country information into this table. When populating your list of countries, use this table instead of XML; display country names and associate country codes with each corresponding list item. Then on selection, use the country code to get the phone code and the 'editable' flag - and act upon this info.

Categories

Resources