2016-08-01 10 views
0

Database structureObjective-C - les données de la base de données Extraction Firebase et remplir dans le tableau

J'ai une configuration de base de données Firebase (s'il vous plaît se référer à l'image).

J'ai un "FeedViewController" pour afficher le contenu de chaque message dans la base de données. Un utilisateur peut publier un ou plusieurs messages.

Lorsque je récupère ces messages de l'instantané Firebase et que je les stocke dans un dictionnaire, je trouve que les valeurs de ce dictionnaire ne sont pas accessibles en dehors de la fonction observeEventType de la base de Firebase. Mon idée était de récupérer ces paires de valeurs-clés, de les stocker sur un objet de classe personnalisé NSObject (Post * post) et d'utiliser cet objet pour charger la vue de table de mon "FeedViewController". À l'intérieur de la fonction observeEventType, je peux accéder aux valeurs de l'objet, mais à l'extérieur, je ne le suis pas. Par conséquent, je ne sais pas comment utiliser ces valeurs pour remplir la vue de table dans mon FeedViewController. Je comprends que cette fonction observeEventType est un rappel asynchrone, mais je ne sais pas comment accéder aux valeurs de l'objet et remplir ma table. Je n'ai pas la moindre idée de ce que la dispatch_async (fonction dispatch_get_main_queue() est en train de faire ici. Toute aide serait très apprécié. Merci!

FeedViewController.m

#import "FeedViewController.h" 
#import "Post.h" 
#import "BackgroundLayer.h" 
#import "SimpleTableCell.h" 
#import "FBSDKCoreKit/FBSDKCoreKit.h" 
#import "FBSDKLoginKit/FBSDKLoginKit.h" 
#import "FBSDKCoreKit/FBSDKGraphRequest.h" 
@import Firebase; 
@import FirebaseAuth; 
@import FirebaseStorage; 
@import FirebaseDatabase; 

@interface FeedViewController() 

@property (strong, nonatomic) Post *post; 

@end 

@implementation FeedViewController 

-(void) viewDidLoad { 

[super viewDidLoad]; 

_ref = [[FIRDatabase database] reference]; 

self.post = [[Post alloc] init]; 

/* 

_idArr = [[NSMutableArray alloc] init]; 


_postDict = [[NSMutableDictionary alloc] init]; 
_idDict = [[NSMutableDictionary alloc] init]; 
_postID = [[NSMutableArray alloc] init]; 

_userName = [[NSMutableArray alloc] init]; 
_placeName = [[NSMutableArray alloc] init]; 
_addressLine1 = [[NSMutableArray alloc] init]; 
_addressLine2 = [[NSMutableArray alloc] init]; 
_ratings = [[NSMutableArray alloc] init]; 
_desc = [[NSMutableArray alloc] init]; 
_userEmail = [[NSMutableArray alloc] init]; 
_userIDArray = [[NSMutableArray alloc] init]; 
*/ 
[self fetchData]; 

NSLog(@"Emails: %@", _post.userID); 


} 

-(void) viewWillAppear:(BOOL)animated { 

[super viewWillAppear:animated]; 

CAGradientLayer *bgLayer = [BackgroundLayer blueGradient]; 
bgLayer.frame = self.view.bounds; 
[self.view.layer insertSublayer:bgLayer atIndex:0]; 

FIRUser *user = [FIRAuth auth].currentUser; 

if (user != nil) 
{ 
    //fbFirstName.text = user.displayName; 
    //fbEmail.text = user.email; 
    NSURL *photoUrl = user.photoURL; 
    NSString *userID = user.uid; 
    //NSString *uploadPath = [userID stringByAppendingString:@"/profile_pic.jpg"]; 
    //NSData *data = [NSData dataWithContentsOfURL:photoUrl]; 
    //ProfilePic.image = [UIImage imageWithData:data]; 

    FIRStorage *storage = [FIRStorage storage]; 
    FIRStorageReference *storageRef = [storage referenceForURL:@"gs://foodsteps-cee33.appspot.com"]; 

    NSString *access_token = [[NSUserDefaults standardUserDefaults] objectForKey:@"fb_token"]; 

    FBSDKGraphRequest *friendList = [[FBSDKGraphRequest alloc] 
            initWithGraphPath:@"me?fields=friends" 
           parameters:nil 
            tokenString: access_token 
            version:nil 
            HTTPMethod:@"GET"]; 

    [friendList startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, 
              id result, 
              NSError *error) { 

     if(error == nil) 
     { 
      //NSLog(@"%@", result); 
      NSDictionary *dictionary = (NSDictionary *)result; 
      NSDictionary *dict = [dictionary objectForKey:@"friends"]; 

      _idArray = [[NSMutableArray alloc] init]; 

      for(int i = 0; i < [[dict objectForKey:@"data"] count]; i++) { 

       [_idArray addObject:[[[dict objectForKey:@"data"] objectAtIndex:i] valueForKey:@"id"]]; 
      } 

      //NSLog(@"%@", idArray); 
     } 

     else { 
      NSLog(@"%@",error); 
     } 
    }]; 


} 
} 

-(void) fetchData { 

_refHandle = [[_ref child:@"users"]  observeEventType:FIRDataEventTypeValue 
              withBlock:^(FIRDataSnapshot * _Nonnull snapshot) 
       { 
        NSDictionary *postDict = snapshot.value; 
        NSLog(@"%@", postDict); 

        for(NSString *aKey in [postDict allKeys]) 
        { 
         // do something like a log: 
         _post.userID = aKey; 
        } 

        //_post. 
        //[_post setValuesForKeysWithDictionary:postDict]; 
        [self.tableView reloadData]; 

      }]; 

NSLog(@"Emails: %@", _post.userID); 

dispatch_async(dispatch_get_main_queue(), ^{ 

[self.tableView reloadData]; 

}); 
} 

-(void) viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[_ref child:@"users"] removeObserverWithHandle:_refHandle]; 
} 

@end 

Post.m

#import "Post.h" 

@implementation Post 


- (instancetype)init { 

return [self initWithUid:@"" 
       andPostid:@"" 
      andUsername:@"" 
       andDesc:@"" 
       andRatings:@"" 
      andPlacename:@"" 
     andAddressLine1:@"" 
     andAddressLine2:@"" 
       andEmail:@""]; 
} 

- (instancetype)initWithUid:(NSString *)userID 
      andPostid:(NSString *)postID 
andUsername: (NSString *)userName 
andDesc:(NSString *)desc 
andRatings:(NSString *)ratings 
andPlacename: (NSString *)placeName 
andAddressLine1: (NSString *)addressLine1 
andAddressLine2: (NSString *)addressLine2 
andEmail: (NSString *)userEmail { 

self = [super init]; 
if(self) { 
    self.userID = userID; 
    self.postID = postID; 
    self.userName = userName; 
    self.desc = desc; 
    self.ratings = ratings; 
    self.placeName = placeName; 
    self.addressLine1 = addressLine1; 
    self.addressLine2 = addressLine2; 
    self.userEmail = userEmail; 
} 

return self; 
} 

@end 

Répondre

1

Votre approche est ce que j'ai essayé de faire au début, mais j'ai eu des problèmes pour y accéder dans cellforrowatindexpath.la chose qui fonctionne pour moi est

- (void)configureDatabase :(NSUInteger)postsAmount{ 

_ref = [[FIRDatabase database] reference]; 
// Listen for new messages in the Firebase database 
_refHandle = [[[[_ref child:@"posts"]queryOrderedByKey] queryLimitedToLast:postsAmount]observeEventType:FIRDataEventTypeChildAdded withBlock:^(FIRDataSnapshot *snapshot) { 

     [_posts insertObject:snapshot atIndex:0]; 
    }]; 
} 

Puis, en viewdidappear

 [self configureDatabase:_numberOfPosts]; 

puis enfin

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

FIRDataSnapshot *postsSnapshot = _posts[indexPath.section]; 

NSDictionary *post = postsSnapshot.value; 
//use key values to create your views. 
} 

comprennent également

@property (strong, nonatomic) NSMutableArray<FIRDataSnapshot *> *posts; 

Ce que cela fait est des requêtes Firebase pour vos valeurs et reçoit des instantanés. ces instantanés sont ensuite placés dans votre tableau _posts et vous pouvez y accéder dans d'autres méthodes.