Ionic3 get firebase data too slow to list it - firebase

constructor(public navCtrl: NavController,public navParams : NavParams,
public modalCtrl:ModalController, private afAuth:AngularFireAuth, private afDatabase:AngularFireDatabase , public fb:FirebaseService) {
this.getDefaults();
this.selectedExercise=[];
console.log("home");
this.exercises=this.fb.getShoppingItems();
console.log(this.exercises);
at home.ts file,
at constructor, I get firebase data from firebase provider that I made to show it on list on html.
but the problem is that I logged it console.log(this.exercises) which is the data that I want to show on list, but it came null.
but after logged null, firebase provider get data from firebase and logged it
as you can see below.
I think browser should wait until firebase provider get data then should list it.
but don't know how to do it.

This is the way you should go
You need to change your getShoppingItems method to return a promise object like this
getShoppingItems(){
return new Promise<any>((resolve, reject) => {
this.db.list("/profile/user_id").subscribe(result =>{
resolve(result));
}
});
}
Your constructor method should get the result like this
constructor(
public navCtrl: NavController,
public navParams : NavParams,
public modalCtrl:ModalController,
private afAuth:AngularFireAuth,
private afDatabase:AngularFireDatabase ,
public fb:FirebaseService) {
this.getDefaults();
this.selectedExercise=[];
console.log("home");
//get your result like this
this.fb.getShoppingItems().then(result =>{
this.exercises = result;
console.log(this.exercises);
});
}

use the async pipe:
*ngFor="let item of exercises | async"
with
exercises = this.afd.list('...');

Related

Flutter - Mockito Firestore...get() - The method 'document' was called on null

for learning purposes I am trying to mock a Firestore controller class with Mockito.
firestore_controller.dart
import 'package:cloud_firestore/cloud_firestore.dart';
class FirestoreController implements FirestoreControllerInterface {
final Firestore firestoreApi;
FirestoreController({this.firestoreApi});
#override
Future<DocumentSnapshot> read() async {
final DocumentSnapshot document = await this.firestoreApi.collection('user').document('user_fooBar').get();
return document;
}
}
firestore_controller_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:mockito/mockito.dart';
import 'package:fooApp/Core/repositories/firebase/firestore_controller.dart';
class MockFirestoreBackend extends Mock implements Firestore {}
class MockDocumentSnapshot extends Mock implements DocumentSnapshot {}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group("Firebase Controller", () {
final Firestore firestoreMock = MockFirestoreBackend();
final MockDocumentSnapshot mockDocumentSnapshot = MockDocumentSnapshot();
FirestoreController sut;
test("try to read a document", () async {
// Arrange
final Map<String, dynamic> _fakeResponse = {
'foo': 123,
'bar': 'foobar was here',
};
sut = FirestoreController(firestoreApi: firestoreMock); // INJECT MOCK
// Arrange: Mock
when(firestoreMock.collection('user').document('user_fooBar').get()).thenAnswer((_) => Future<MockDocumentSnapshot>.value(mockDocumentSnapshot));
when(mockDocumentSnapshot.data).thenReturn(_fakeResponse);
// Act
final fakeDocument = await sut.read();
});
});
}
🚨 Console Output 🚨
NoSuchMethodError: The method 'document' was called on null.
Receiver: null
Tried calling: document("user_fooBar")
sorry if the mistake is obvious, this is the first time I've used Mockito
Where's my error? What do I miss? Thanks a lot!
try this:
https://pub.dev/packages/cloud_firestore_mocks
A test I've done using it:
class MockFirestore extends Mock implements Firestore {}
class MockDocument extends Mock implements DocumentSnapshot {}
void main() {
final _tAppointmentModel = AppointmentModel(
appointmentID: kAppointmentID,
date: DateTime.parse("2020-12-05 20:18:04Z"),
description: "test description",
doctorID: kDoctorID,
hospitalID: kHospitalID,
infantID: kInfantID,
);
group('AppointmentModel tests: ', () {
final tAppointmentID = kAppointmentID;
final tInfantID = kInfantID;
final tDoctorID = kDoctorID;
final tHospitalID = kHospitalID;
test('should be a subclass of Appointment', () async {
expect(_tAppointmentModel, isA<Appointment>());
});
test('store and retrieve document from Firestore', () async {
final instance = MockFirestoreInstance();
await instance.collection('appointments').add({
'appointmentID': tAppointmentID,
'date': DateTime.parse("2020-12-05 20:18:04Z"),
'description': "test description",
'doctorID': tDoctorID,
'hospitalID': tHospitalID,
'infantID': tInfantID,
});
final snapshot = await instance.collection('appointments').getDocuments();
final String expected = _tAppointmentModel.props[0];
final String result = snapshot.documents[0].data['appointmentID'];
expect(expected, result);
});
});
}
So I think I've found why this is - it appears to be a bug(ette) in Mockito, in that it doesn't handle the "dot walk" from collection(any) to document() or getDocuments(). I fixed it like this:
declare five classes:
class MockFirebaseClient extends Mock implements Firestore {} //for your mock injection
class MockCollectionReference extends Mock implements CollectionReference {} //for when declaration
class MockQuerySnapshot extends Mock implements QuerySnapshot {} //for the thenAnswer return on collection of docs
class MockDocumentReference extends Mock implements DocumentReference {} //for single doc query
class MockDocumentSnapshot extends Mock implements DocumentSnapshot {} // for the thenAnswer return on single doc query
Do your setup etc - then the when clauses are just:
when(mockCollectionReference.getDocuments())
.thenAnswer((_) => Future.value(mockQuerySnapshot)); //for collection of docs query
when(mockDocumentReference.get())
.thenAnswer((_) => Future.value(mockDocumentSnapshot)); //for single doc query

Unable to populate JavaFX tableview with Twitter Search API response using Gluon Connect

I am unable to populate a JavaFX Tableview with Twitter Search API response using Gluon Connect. I am trying to populate a JavaFX table with Date/Time, User and their Tweet.
I have setup a connection to the NewsAPI and successfully retrieved the JSON and was able to populate my Table.
I followed exactly the same approach with connecting to the Twitter Search API. I have tested the connection on Postman and it works.
I can't figure out whether I've created the RestClient incorrectly or if I'm not handling the response correctly or the issue is related to something else.
I've done GluonObservableList .isInitialised() and get False. Which indicates the GluonObservableList has not initialised.
This is my code for the NEWS API which works perfectly.
// create a RestClient to the specific URL
RestClient NewsRestClient = RestClient.create()
.method("GET")
.host("https://newsapi.org")
.path("//v2/everything?q=GBP_USD&from=2019-08-21&to=2019-08-21&sortBy=popularity&apiKey=9a7a9daab76f440fb796350c83db0694");
InputStreamIterableInputConverter<Article> converter = new ArticlesIterableInputConverter<>(Article.class);
GluonObservableList<Article> articles = DataProvider.retrieveList(NewsRestClient.createListDataReader(converter));
articles.initializedProperty().addListener((obv,ov,nv)-> {
newsTbl.setItems(articles);
newsDateCol.setCellValueFactory(new PropertyValueFactory<>("publishedAt"));
newsPublisherCol.setCellValueFactory((new PropertyValueFactory<>("name")));
newsTitleCol.setCellValueFactory(new PropertyValueFactory<>("title"));
newsURLCol.setCellValueFactory(new PropertyValueFactory<>("url"));
});
This is the code for my Twitter API which doesn't work.
RestClient TwitterRestClient = RestClient.create()
.method("GET")
.host("https://api.twitter.com")
.path("/1.1/search/tweets.json?q=USD_GBP")
.consumerKey("XXXXXXXXXX")
.consumerSecret("XXXXXXXX");
InputStreamIterableInputConverter<Tweet> converter2 = new TwitterIterableInputConverter<>(Tweet.class);
GluonObservableList<Tweet> tweets = DataProvider.retrieveList(TwitterRestClient.createListDataReader(converter2));
System.out.println(tweets.initializedProperty());
System.out.println(tweets.isInitialized());
tweets.initializedProperty().addListener((obv,ov,nv)-> {
twitterTbl.setItems(tweets);
twTime.setCellValueFactory(new PropertyValueFactory<>("created_at"));
twUserID.setCellValueFactory((new PropertyValueFactory<>("name")));
twTweet.setCellValueFactory(new PropertyValueFactory<>("text"));
});
This is my POJO
public class Tweet {
private String text;
private String created_at;
private User user;
public Tweet() {
}
public String getName() {
return user.getName();
}
public Tweet(String text, String created_at, User user) {
this.text = text;
this.created_at = created_at;
this.user = user;
}
public String getText() {
return text;
}
public String getCreated_at() {
return created_at;
}
#Override
public String toString() {
return "Tweet{"+",text='"+text+'\''+", created_at='"+created_at+'\'' +'}';
}
public static class User {
String name;
public String getName() {
return this.name;
}
}
}
To troubleshoot I ran
System.out.println(tweets.initializedProperty());
System.out.println(tweets.isInitialized());
This is the output i get ...
BooleanProperty [bean: [], name: initialized, value: false]
false
System.out.println(tweets.exceptionProperty());
ObjectProperty [bean: [], name: exception, value: null]

Get a collection using user uid to generate Firestore reference

I want to set a firestore collection in a service to later return an observable of its documents
#Injectable()
export class ContactService {
private contactCollection: AngularFirestoreCollection<any>;
private contactDocument: AngularFirestoreDocument<any>;
constructor(
private authService: AuthService,
private afs: AngularFirestore
) {
this.authService.user
.subscribe(user => this.contactCollection = this.afs.collection(`directories/${user.uid}/contacts`));
}
getContacts(){
return this.contactCollection.valueChanges()
}
this works fine if i navigate to the route that displays the component that consume the service but if i visit directly the route or refresh the page the contactCollection is undefined.
Any ideas why is this happening?

Map<string,string> variable is not getting added in DynamoDB Local but works well in Real DynamoDB

I am trying to add Map variable using Spring for DynamoDb plugin into DynamoDbLocal database .... It doesnt give any error when I write but when I read the same variable I get a null value against the map request.
This datatype is by default managed by DynamoDbMapper I believe. Do you have any idea what wrong or what needs to be done ?
Here's my domain code
package com.wt.domain;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.annotation.Id;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#DynamoDBTable(tableName = "Notification")
#AllArgsConstructor
#NoArgsConstructor
public class Notification implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#DynamoDBIgnore
private NotificationCompositeKey notificationCompositeKey = new NotificationCompositeKey();
#Getter
#Setter
#DynamoDBAttribute // This is the Map - Giving Null when read
private Map<String,String> jsonMessage = new HashMap<String, String>();
#DynamoDBHashKey(attributeName = "identityId")
public String getIdentityId() {
return notificationCompositeKey.getIdentityId();
}
public void setIdentityId(String identityId) {
notificationCompositeKey.setIdentityId(identityId);
}
public void setTimestamp(long timestamp) {
notificationCompositeKey.setTimestamp(timestamp);
}
#DynamoDBRangeKey(attributeName = "notificationTimestamp")
public long getTimestamp() {
return notificationCompositeKey.getTimestamp();
}
}
Firstly, I presume that you have tested the code connecting to real DynamoDB on some deployed environment rather than on local.
I think, the problem is not on local DynamoDB. The problem should be the way you create getter and setter using lombok API. If you remove the lombok getter and setter annotation and add the getter/setter manually. It should work on local Dynamodb as well. I have seen this behavior.
#DynamoDBAttribute(attributeName = "jsonMessage")
public Map<String, String> getJsonMessage() {
return jsonMessage;
}
public void setJsonMessage(Map<String, String> jsonMessage) {
this.jsonMessage = jsonMessage;
}
Thanx guys - The issue got resolved and the problem was that I kept a condition if the value is null then insert blank string for that key-value in the map.
Even as per the AWS Documentation - it wont allow the Map or the List Datatype to be entered if the value is null or blank.

Ionic 2/Firebase - Reorder items from Firebase

I am currently making an Ionic 2 application. I would like the user to be able to reorder a list of items that is displayed from the database. However, I keep getting this error:
TypeError: array.splice is not a function at reorderArray
There seem to be a problem with my FirebaseListObservable but I do not know what it is. Any help is much appreciated!
Below is my code for the following:
export class ManageFavouritesPage {
fireAuth: any;
items: FirebaseListObservable<any[]>;
constructor(public navCtrl: NavController, public af: AngularFire, private toastCtrl: ToastController, public authData: AuthData) {
let userid = this.authData.getID();
this.items = af.database.list(`/users/${userid}/favourites`)
console.log(this.items);
}
reorderItems(indexes) {
this.items = reorderArray(this.items, indexes)
}

Resources