I am trying to change values of my class from an override method as shown below:
public class QuestionAnalyser extends AppCompatActivity {
String question;
String entityIdentified;
static boolean identified = false;
DatabaseReference entityRef;
TranslatorServant t = new TranslatorServant();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interface);
}
public void analyse(String userQues) {
if (!(Interface.deviceLang.equals("en"))) {
TranslatorServant t = new TranslatorServant();
question = t.translateText(userQues);
} else {
question = userQues;
}
question = question.replaceAll("\\p{Punct}|\\d", "");
final String[] words = question.split(" ");
getEntity(words);
if (identified == true) {
initialiseEntityServant(entityIdentified, question, words);
} else {
mimicOtherMessage("Sorry, I have failed to understand your question");
}
return;
}
private void getEntity(final String[] words) {
entityRef = FirebaseDatabase.getInstance().getReference().child("IRAdata").child("Entities");
entityRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot entity : dataSnapshot.getChildren()) {
String[] synonyms = entity.child("syn").getValue().toString().split(",");
for (String syn : synonyms) {
for (String word : words) {
if (word.equalsIgnoreCase(syn) || question.equalsIgnoreCase(syn)) {
mimicOtherMessage("found");
entityIdentified = entity.getKey();
identified = true;
}
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
if (identified == false) {
for (String yes : YesNo.yes) {
for (String w : words) {
if (w.equalsIgnoreCase(yes) || question.equalsIgnoreCase(yes)) {
identified = true;
entityIdentified="basic";
}
}
for (String no : YesNo.no) {
for (String w : words) {
if (w.equalsIgnoreCase(no) || question.equalsIgnoreCase(no)) {
identified = true;
entityIdentified="basic";
}
}
}
}
}
return;
}
}
From the analyse() method i am calling the getEntity() method, the override method is working fine and is changing the value of identified and entityIdentified accordingly but, when the method is completed the updates are not reflected on the variables.
I have tried to debug, i could see the values changing in the override method, but when i check the values of the variables after the override method, i could only get the initial values. Somebody can help me on this please?
I have tried implementing threads as well, to make sure the method getEntity() gets completed before returning to the main, but the problem persists.
The code you have written is not very detailed to me, but your logic could be restructured in a way, similar to what I have done below:
public class QuestionAnalyser extends AppCompatActivity {
String question;
String entityIdentified;
static boolean identified = false;
DatabaseReference entityRef;
TranslatorServant t = new TranslatorServant();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_interface);
}
public void analyse(String userQues) {
if (!(Interface.deviceLang.equals("en"))) {
TranslatorServant t = new TranslatorServant();
question = t.translateText(userQues);
} else {
question = userQues;
}
question = question.replaceAll("\\p{Punct}|\\d", "");
final String[] words = question.split(" ");
getEntity(words);
// remove any logic that depends on the return of getEntity(words) from here
// it is best if the logic is called from within the Firebase call
}
private void getEntity(final String[] words) {
entityRef = FirebaseDatabase.getInstance().getReference().child("IRAdata").child("Entities");
entityRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot entity : dataSnapshot.getChildren()) {
String[] synonyms = entity.child("syn").getValue().toString().split(",");
for (String syn : synonyms) {
for (String word : words) {
if (word.equalsIgnoreCase(syn) || question.equalsIgnoreCase(syn)) {
mimicOtherMessage("found");
entityIdentified = entity.getKey();
identified = true;// under what condition will this be false
// this is the best place to put the logic
initialiseEntityServant(entityIdentified, question, words);
} else {
identified = false;// I hope this condition for setting it to false is satisfactory
mimicOtherMessage("Sorry, I have failed to understand your question");
for (String yes : YesNo.yes) {
for (String w : words) {
if (w.equalsIgnoreCase(yes) || question.equalsIgnoreCase(yes)) {
identified = true;
entityIdentified = "basic";
}
}
for (String no : YesNo.no) {
for (String w : words) {
if (w.equalsIgnoreCase(no) || question.equalsIgnoreCase(no)) {
identified = true;
entityIdentified = "basic";
}
}
}
}
}
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(getApplicationContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
// the logic here will have to also be moved into the Firebase call
}
}
Note that, the parts that required the check on identified have all been moved to the onDataChanged method.
Please move your code written after getEntity()
Inside onDataChange() method. When onDataChange() completes it will execute added code. You will get latest values in variables.
Related
I have three methods:
The first checks the gender of the user
The second checks the housing assortment type
The third puts the sorted users into my card adapter
My issue is with the second method checkHousing(). If the user chooses Same Sex housing it checks all the other Males who have selected Same Sex housing.Vice-versa for the Female users. So far Iv only been able to get all the the users who have chosen Same Sex, both male and female.
Any suggestions? I feel like there is a more efficient way to do this but cant seem to figure it out.
By the way, I'm using Firebase Real Time database to store the user's info.
private String userSex;
private String thisUserSex;
public void checkUserSex() {
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference userDb = usersDb.child(user.getUid());
userDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.child("sex").getValue() != null) {
userSex = dataSnapshot.child("sex").getValue().toString();
switch (userSex) {
case "Male":
thisUserSex = "Male";
break;
case "Female":
thisUserSex = "Female";
break;
}
checkHousing();
} } }
#Override
public void onCancelled(DatabaseError databaseError) {
} }); }
private String housingType;
private String assortment;
public void checkHousing() {
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final DatabaseReference userDb = usersDb.child(user.getUid());
userDb.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.child("Housing").getValue() != null) {
housingType = dataSnapshot.child("Housing").getValue().toString();
switch (housingType) {
case "Same Sex":
assortment = "Same Sex";
break;
case "Uni-Sex":
assortment = "Uni-Sex";
break;
} if (assortment == "Same Sex") dataSnapshot.getValue().toString().equals(thisUserSex);
else { assortment = "UniSex";
}
}
}getRoomMates();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void getRoomMates(){
usersDb.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.child("Housing").getValue() != null) {
if (dataSnapshot.exists() &&
!dataSnapshot.child("connections").child("nope").hasChild(currentUId) &&
!dataSnapshot.child("connections").child("yeps").hasChild(currentUId) &&
dataSnapshot.child("Housing").getValue().toString().equals(assortment)) {
String profileImageUrl = "default";
if (!dataSnapshot.child("profileImageUrl").getValue().equals("default")) {
profileImageUrl =
dataSnapshot.child("profileImageUrl").getValue().toString();
}
cards item = new cards(dataSnapshot.getKey(),
dataSnapshot.child("name").getValue().toString(), profileImageUrl);
rowItems.add(item);
arrayAdapter.notifyDataSetChanged();
} } }
You could split the Same Sex into Same SexM andSame SexF and store those seperatley, and then chose the roommates based on the M or F in the database.
Inside of the switch:
if(thisUserSex.equalsIgnoreCase("Male"){
assortment = "Same SexM";
}else{
assortment = "Same SexF";
}
Check what information is in the database, I have had instances where the data is not being changed during run time and that might be the cause of it always returning the same result. I know that you can use a debug mode in most editors or you can print out the current value for the string housing type.
Edit: Looking closer at the code you are using a real time database so check if the information you are submitting is getting processed correctly.
I am new in Android and working on an Android app which can retrieve data from firebase. There is a weird problem. I already successfully implemented the retrieving function for one data model of my program, and I used same codes just changed the variables but it doesn't work for another data model. I did many tests and I think the problem is in FirebaseHelper cuz there is no any data returned from the data snapshot. The error is
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
The codes are shown below:
The Activity that shows the retrieved data in a listview.
public class TimeTableActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper firebasehelper;
TimeTableAdapter adapter;
ListView lv_CourseList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time_table);
//GET INTENT
Intent intent = this.getIntent();
String majorID = intent.getStringExtra("MAJOR_ID");
lv_CourseList = (ListView) findViewById(R.id.lv_CourseList);
//INITIALIZE FIREBASE DB
db= FirebaseDatabase.getInstance().getReference();
firebasehelper=new FirebaseHelper(db);
//ADAPTER
adapter = new TimeTableAdapter(getApplicationContext(),firebasehelper.retrieveCourse(majorID, new CourseCallbacks() {
#Override
public void onCourseCallback(ArrayList<CourseInfo> courseInfos) {
lv_CourseList.setAdapter(adapter);
}
}));
lv_CourseList.setAdapter(adapter);
}
}
FirebaseHelper:
public class FirebaseHelper{
private DatabaseReference db;
private ArrayList<Major> majors = new ArrayList<>();
private ArrayList<CourseInfo> courseInfos = new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//Save the Major info. into db
public Boolean saveMajor(Major major)
{
Boolean saved = null;
if(major==null)
{
saved =false;
}else
{
try
{
db.child("Major").push().setValue(major);
saved =true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved =false;
}
}
return saved;
}
//Save the Course info. into db
public Boolean saveCourse(CourseInfo courseInfo)
{
Boolean saved = null;
if(courseInfo==null)
{
saved =false;
}else
{
try
{
db.child("CourseInfo").push().setValue(courseInfo);
saved =true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved =false;
}
}
return saved;
}
public ArrayList<Major> retrieveMajor(final MajorCallbacks majorCallbacks){
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Major major = ds.getValue(Major.class);
if (major != null && major.getMajor_id() != null) {
majors.add(major);
}
}
majorCallbacks.onMajorCallback(majors);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Major major = ds.getValue(Major.class);
if (major != null && major.getMajor_id() != null) {
majors.add(major);
}
}
majorCallbacks.onMajorCallback(majors);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
db.addChildEventListener(childEventListener);
if (!majors.isEmpty()){
db.removeEventListener(childEventListener);
}
return majors;
}
public ArrayList<CourseInfo> retrieveCourse(String majorID, final CourseCallbacks courseCallbacks){
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
CourseInfo courseInfo = ds.getValue(CourseInfo.class);
if (courseInfo != null && courseInfo.getCourse_id() != null) {
courseInfos.add(courseInfo);
}
}
courseCallbacks.onCourseCallback(courseInfos);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
CourseInfo courseInfo = ds.getValue(CourseInfo.class);
if (courseInfo != null && courseInfo.getCourse_id() != null) {
courseInfos.add(courseInfo);
}
}
courseCallbacks.onCourseCallback(courseInfos);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
db.child("CourseInfo").orderByChild("major_id").equalTo(majorID).addChildEventListener(childEventListener);
return courseInfos;
}
}
The retrieveMajor method works well even though it returns many null data and repetitive data, and I used the codes of retrieveMajor in retrieveCourse. It doesn't work, the courseInfos is always null. Even though I changed db.child("CourseInfo").orderByChild("major_id").equalTo(majorID).addChildEventListener(childEventListener);
to
db.addChildEventListener(childEventListener);
,still nothing is retrieved which means the problem is not the query (Probably the query is also wrong).
Adapter:
public class TimeTableAdapter extends BaseAdapter {
Context context;
ArrayList<CourseInfo> courseInfos;
public TimeTableAdapter(Context context, ArrayList<CourseInfo> courseInfos) {
this.context = context;
this.courseInfos = courseInfos;
}
#Override
public int getCount() {
return courseInfos.size();
}
#Override
public Object getItem(int pos) {
return courseInfos.get(pos);
}
#Override
public long getItemId(int pos) {
return pos;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
LayoutInflater inflater = LayoutInflater.from(context);
if(convertView == null)
{
convertView= LayoutInflater.from(context).inflate(R.layout.model_timetable,viewGroup,false);
}
TextView tv_courseid= (TextView) convertView.findViewById(R.id.tv_courseid);
TextView tv_coursename= (TextView) convertView.findViewById(R.id.tv_coursename);
TextView tv_courseinstructor= (TextView) convertView.findViewById(R.id.tv_courseinstructor);
TextView tv_courseavailable= (TextView) convertView.findViewById(R.id.tv_courseavailable);
final CourseInfo courseInfo= (CourseInfo) this.getItem(position);
tv_courseid.setText(courseInfo.getCourse_id());
tv_coursename.setText(courseInfo.getCourse_name());
tv_courseinstructor.setText(courseInfo.getCourse_instructor());
tv_courseavailable.setText(courseInfo.getCourse_available());
return convertView;
}
}
Data model:
#IgnoreExtraProperties
public class CourseInfo {
public String course_id;
public String course_name;
public int course_section;
public String course_type;
public double course_crdhrs;
public String course_days;
public String course_times;
public String course_location;
public int course_max;
public int course_cur;
public int course_available;
public int course_wl;
public double course_per;
public String course_instructor;
public String course_description;
public String course_prerequire;
public String major_id;
public CourseInfo() {
}
public CourseInfo(String course_id, String course_name, int course_section, String course_type, double course_crdhrs, String course_days, String course_times, String course_location, int course_max, int course_cur, int course_available, int course_wl, double course_per, String course_instructor, String course_description, String course_prerequire, String major_id) {
this.course_id = course_id;
this.course_name = course_name;
this.course_section = course_section;
this.course_type = course_type;
this.course_crdhrs = course_crdhrs;
this.course_days = course_days;
this.course_times = course_times;
this.course_location = course_location;
this.course_max = course_max;
this.course_cur = course_cur;
this.course_available = course_available;
this.course_wl = course_wl;
this.course_per = course_per;
this.course_instructor = course_instructor;
this.course_description = course_description;
this.course_prerequire = course_prerequire;
this.major_id = major_id;
}
public String getCourse_id() {
return course_id;
}
public String getCourse_name() {
return course_name;
}
public int getCourse_section() {
return course_section;
}
public String getCourse_type() {
return course_type;
}
public double getCourse_crdhrs() {
return course_crdhrs;
}
public String getCourse_days() {
return course_days;
}
public String getCourse_times() {
return course_times;
}
public String getCourse_location() {
return course_location;
}
public int getCourse_max() {
return course_max;
}
public int getCourse_cur() {
return course_cur;
}
public int getCourse_available() {
return course_available;
}
public int getCourse_wl() {
return course_wl;
}
public double getCourse_per() {
return course_per;
}
public String getCourse_instructor() {
return course_instructor;
}
public String getCourse_description() {
return course_description;
}
public String getCourse_prerequire() {
return course_prerequire;
}
public String getMajor_id() {
return major_id;
}
}
If you need more codes or information, please comment and let me know. I will really appreciate if you can also help me solve the null data and repetitive data problem cuz it makes the listview show many blank and repetitive items.
You cannot return something now that hasn't been loaded yet. With other words, you cannot just simply create a method that as a return type, an ArrayList<Major> and in the same time return that object. This is happening because those methods, onChildAdded(), onChildChanged() and so on, have an asynchronous behaviour, which means that are called even before you are getting/updating the data from/in the database. To solve this, you can move the declaration of that ArrayList inside one method and do what you need to do with it or dive into asynchronous world and use the last part of my answer from this post. You can take also a look at this video for a better understanding.
Heterogeneous RecyclerView
Hello friends I have a simple doubt
Here i am adding singleLineText
`addSingleLine.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String singleLineText = singleline.getText().toString();
if(singleLineText.length() != 0)
{
mAdapter.addItem(singleLineText,null);
mAdapter.notifyDataSetChanged();
Log.e(TAG,"adding single line text");
}
singleline.getText().clear();
}
});`
On this part i am adding MultiLineText
` addMultiLine.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String multiLineText = multiline.getText().toString();
String myList[] = multiLineText.split(",");
for(String item : myList)
{
mAdapter.addItem(null,item);
mAdapter.notifyDataSetChanged();
Log.e(TAG,"adding multi line text");
}
multiline.getText().clear();
}
});
}`
My Adapter part of code:
` public void addItem(String singleLineText, String item) {
Model model = new Model();
if(item == null) {
model.setText1(singleLineText);
model.settingSingleLineText(true); // How to identify single line
}
else
{
model.setText2(item);
model.settingMultiLineText(true); // How to identify multiple line
}
modelList.add(model);
}`
GetViewType Method:
` public int getItemViewType(int position) {
if (modelList.get(position).IfSingleLine() != null)
return VERTICAL;
else {
return HORIZONTAL;
}
}`
Model class code snippet:
private Boolean checkSingleLine = null;
public Boolean IfSingleLine()
{
return checkSingleLine;
}
public void settingSingleLineText(Boolean txt1)
{
checkSingleLine = txt1;
}
public void settingMultiLineText(Boolean txt2)
{
checkMultiLine = txt2;
}
`
Problem: How to identify the singleLineText and multiLineText by using the Model Class??
You have a problem with your if (modelList.get(position).IfSingleLine() != null). IfSingleLine() will never be null. You want to check if it is true or false and this is not how you check for that.
Change your getItemViewType to the following and you will get correct orientation result from this function.
public int getItemViewType(int position) {
if (modelList.get(position).IfSingleLine())
return VERTICAL;
else {
return HORIZONTAL;
}
}`
I'm using Youtube API in my app, i'm trying to get a list of videos from Youtube, it's work fine, but it's limit to 48 videos in one list for some reason, when I'm trying to get more than 48 videos in one list, i'm getting 400 ERROR CODE, Here's my code:
public void Load(final Context context, int start, int end, int category, LoaderVideoListener listener) {
try {
mVideosNames.clear();
mVideos.clear();
mCategory = category;
mStart = start;
mEnd = end;
mListener = listener;
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference dataRef = database.getReference();
String child = "Category";
if (mCategory == 1) {
child = "category1";
} else if (mCategory == 2) {
child = "category2";
} else {
child += category;
}
dataRef.child(child).orderByChild("index").startAt(start).endAt(end).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
try {
StringBuilder videoIds = new StringBuilder();
for (DataSnapshot data : dataSnapshot.getChildren()) {
videoIds.append(data.child("YTId").getValue()).append(",");
}
Network net = new Network();
net.Request(context, URL_1 + videoIds + URL_2, new RequestJsonListiner() {
#Override
public void OnResponse(String json, boolean isError, String errorDetails) {
if (!isError) {
try {
ParseJsonToVideoYT(json);
} catch (JSONException e1) {
handleCallBack.obtainMessage(1, e1.getMessage()).sendToTarget();
}
} else
handleCallBack.obtainMessage(1, errorDetails).sendToTarget();
}
});
} catch (Exception e) {
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
handleCallBack.obtainMessage(1, databaseError.getMessage()).sendToTarget();
}
});
} catch (Exception e) {
}
}
400 error means bad request so there's something wrong with your field parameters. Also, note that maxResults in Youtube API list has a maximum value of 50.
This is the code, and it doesn't check if the value in my editText exists.
mSubmitBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String title_val = mPostTitle.getText().toString().trim();
mDatabase2 = FirebaseDatabase.getInstance().getReference().child("Forums");
mDatabase2.child("title").child("KS1: "+title_val).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()) {
String success = "Your title already exists...";
Toast.makeText(PostActivityKinderSection1.this, success, Toast.LENGTH_LONG).show();
mSubmitBtn.setEnabled(true);
}
else {
mSubmitBtn.setEnabled(false);
startPosting();
}
}
});
}
});
I want to avoid saving multiple times with the same title in my firebase.
You can not only check if title child exist, you have to iterate over all forums to find out if there is already one with title you want to save. You can do it like this:
final String title_val = "KS1: " + mPostTitle.getText().toString().trim();
mDatabase2 = FirebaseDatabase.getInstance().getReference().child("Forums");
mDatabase2.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
void onDataChange(DataSnapshot forumsSnapshot) {
boolean isTitleAlreadyUsed = false;
for (DataSnapshot specificForum : forumsSnapshot.getChildren()) {
// Check if key 'title' exists and if title value is equal to value to save (title_val)
if (specificForum.hasChild("title") && (title_val.equals(specificForum.child("title").getValue()))){
isTitleAlreadyUsed = true;
}
}
if (isTitleAlreadyUsed) {
String success = "Your title already exists...";
Toast.makeText(PostActivityKinderSection1.this, success, Toast.LENGTH_LONG).show();
mSubmitBtn.setEnabled(true);
}
else {
mSubmitBtn.setEnabled(false);
startPosting();
}
}
}
If you have performance issue try to replace for-loop with while-loop, or use the title as child key in your db construction.