mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
348 lines
13 KiB
Plaintext
348 lines
13 KiB
Plaintext
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "sky/services/firebase/ios/firebase_impl.h"
|
|
#include "base/logging.h"
|
|
#include "base/strings/sys_string_conversions.h"
|
|
|
|
#import <Firebase.h>
|
|
|
|
namespace sky {
|
|
namespace services {
|
|
namespace firebase {
|
|
|
|
::firebase::DataSnapshotPtr toMojoSnapshot(FDataSnapshot* snapshot) {
|
|
::firebase::DataSnapshotPtr mojoSnapshot(::firebase::DataSnapshot::New());
|
|
mojoSnapshot->key = base::SysNSStringToUTF8(snapshot.key);
|
|
NSDictionary *valueDictionary = @{@"value": snapshot.value};
|
|
NSData *data = [NSJSONSerialization dataWithJSONObject:valueDictionary
|
|
options:0
|
|
error:nil];
|
|
if (data != nil) {
|
|
NSString *jsonValue = [[NSString alloc] initWithData:data
|
|
encoding:NSUTF8StringEncoding];
|
|
mojoSnapshot->jsonValue = base::SysNSStringToUTF8(jsonValue);
|
|
}
|
|
return mojoSnapshot.Pass();
|
|
}
|
|
|
|
::firebase::ErrorPtr toMojoError(NSError* error) {
|
|
::firebase::ErrorPtr mojoError(::firebase::Error::New());
|
|
mojoError->code = error.code;
|
|
mojoError->message = base::SysNSStringToUTF8(error.description);
|
|
return mojoError.Pass();
|
|
}
|
|
|
|
::firebase::AuthDataPtr toMojoAuthData(FAuthData* authData) {
|
|
::firebase::AuthDataPtr mojoAuthData(::firebase::AuthData::New());
|
|
mojoAuthData->uid = base::SysNSStringToUTF8(authData.uid);
|
|
mojoAuthData->provider = base::SysNSStringToUTF8(authData.provider);
|
|
mojoAuthData->token = base::SysNSStringToUTF8(authData.token);
|
|
return mojoAuthData.Pass();
|
|
}
|
|
|
|
FirebaseImpl::FirebaseImpl(mojo::InterfaceRequest<::firebase::Firebase> request)
|
|
: binding_(this, request.Pass()) {}
|
|
|
|
FirebaseImpl::~FirebaseImpl() {
|
|
[client_ release];
|
|
}
|
|
|
|
void FirebaseImpl::InitWithUrl(const mojo::String& url) {
|
|
client_ = [[[::Firebase alloc] initWithUrl:@(url.data())] retain];
|
|
}
|
|
|
|
void FirebaseImpl::AddValueEventListener(::firebase::ValueEventListenerPtr ptr) {
|
|
::firebase::ValueEventListener *listener = ptr.get();
|
|
FirebaseHandle handle = [client_ observeEventType:FEventTypeValue
|
|
withBlock:^(FDataSnapshot *snapshot) {
|
|
listener->OnDataChange(toMojoSnapshot(snapshot));
|
|
} withCancelBlock:^(NSError *error) {
|
|
listener->OnCancelled(toMojoError(error));
|
|
}];
|
|
ptr.set_connection_error_handler([this, handle, listener]() {
|
|
[client_ removeObserverWithHandle:handle];
|
|
auto it = std::find_if(value_event_listeners_.begin(),
|
|
value_event_listeners_.end(),
|
|
[listener](const ::firebase::ValueEventListenerPtr& p) {
|
|
return (p.get() == listener);
|
|
});
|
|
DCHECK(it != value_event_listeners_.end());
|
|
value_event_listeners_.erase(it);
|
|
});
|
|
value_event_listeners_.emplace_back(ptr.Pass());
|
|
}
|
|
|
|
void FirebaseImpl::AddChildEventListener(::firebase::ChildEventListenerPtr ptr) {
|
|
::firebase::ChildEventListener *listener = ptr.get();
|
|
void (^cancelBlock)(NSError *) = ^(NSError *error) {
|
|
listener->OnCancelled(toMojoError(error));
|
|
};
|
|
|
|
void (^addedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
|
|
listener->OnChildAdded(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
|
|
};
|
|
FirebaseHandle addedHandle = [client_ observeEventType:FEventTypeChildAdded
|
|
andPreviousSiblingKeyWithBlock:addedBlock
|
|
withCancelBlock:cancelBlock];
|
|
|
|
void (^changedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
|
|
listener->OnChildChanged(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
|
|
};
|
|
FirebaseHandle changedHandle = [client_ observeEventType:FEventTypeChildChanged
|
|
andPreviousSiblingKeyWithBlock:changedBlock
|
|
withCancelBlock:cancelBlock];
|
|
|
|
void (^movedBlock)(FDataSnapshot *, NSString *) = ^(FDataSnapshot *snapshot, NSString *prevKey) {
|
|
listener->OnChildMoved(toMojoSnapshot(snapshot), base::SysNSStringToUTF8(prevKey));
|
|
};
|
|
FirebaseHandle movedHandle = [client_ observeEventType:FEventTypeChildMoved
|
|
andPreviousSiblingKeyWithBlock:movedBlock
|
|
withCancelBlock:cancelBlock];
|
|
|
|
void (^removedBlock)(FDataSnapshot *snapshot) = ^(FDataSnapshot *snapshot) {
|
|
listener->OnChildRemoved(toMojoSnapshot(snapshot));
|
|
};
|
|
FirebaseHandle removedHandle = [client_ observeEventType:FEventTypeChildRemoved
|
|
withBlock:removedBlock
|
|
withCancelBlock:cancelBlock];
|
|
|
|
ptr.set_connection_error_handler(
|
|
[this, addedHandle, changedHandle, movedHandle, removedHandle, listener]() {
|
|
[client_ removeObserverWithHandle:addedHandle];
|
|
[client_ removeObserverWithHandle:changedHandle];
|
|
[client_ removeObserverWithHandle:movedHandle];
|
|
[client_ removeObserverWithHandle:removedHandle];
|
|
auto it = std::find_if(child_event_listeners_.begin(),
|
|
child_event_listeners_.end(),
|
|
[listener](const ::firebase::ChildEventListenerPtr& p) {
|
|
return (p.get() == listener);
|
|
});
|
|
DCHECK(it != child_event_listeners_.end());
|
|
child_event_listeners_.erase(it);
|
|
}
|
|
);
|
|
child_event_listeners_.emplace_back(ptr.Pass());
|
|
}
|
|
|
|
void FirebaseImpl::ObserveSingleEventOfType(
|
|
::firebase::EventType eventType,
|
|
const ObserveSingleEventOfTypeCallback& callback) {
|
|
ObserveSingleEventOfTypeCallback *copyCallback =
|
|
new ObserveSingleEventOfTypeCallback(callback);
|
|
[client_ observeSingleEventOfType:static_cast<FEventType>(eventType)
|
|
withBlock:^(FDataSnapshot *snapshot) {
|
|
copyCallback->Run(toMojoSnapshot(snapshot));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::AuthWithCustomToken(
|
|
const mojo::String& token,
|
|
const AuthWithCustomTokenCallback& callback) {
|
|
}
|
|
|
|
void FirebaseImpl::AuthAnonymously(
|
|
const AuthAnonymouslyCallback& callback) {
|
|
AuthAnonymouslyCallback *copyCallback =
|
|
new AuthAnonymouslyCallback(callback);
|
|
[client_ authAnonymouslyWithCompletionBlock:^(NSError *error, FAuthData *authData) {
|
|
copyCallback->Run(toMojoError(error), toMojoAuthData(authData));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::AuthWithOAuthToken(
|
|
const mojo::String& provider,
|
|
const mojo::String& credentials,
|
|
const AuthWithOAuthTokenCallback& callback) {
|
|
AuthWithOAuthTokenCallback *copyCallback =
|
|
new AuthWithOAuthTokenCallback(callback);
|
|
[client_ authWithOAuthProvider:@(provider.data())
|
|
token:@(credentials.data())
|
|
withCompletionBlock:^(NSError *error, FAuthData *authData) {
|
|
copyCallback->Run(toMojoError(error), toMojoAuthData(authData));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::AuthWithPassword(
|
|
const mojo::String& email,
|
|
const mojo::String& password,
|
|
const AuthWithPasswordCallback& callback) {
|
|
AuthWithPasswordCallback *copyCallback =
|
|
new AuthWithPasswordCallback(callback);
|
|
[client_ authUser:@(email.data())
|
|
password:@(password.data())
|
|
withCompletionBlock:^(NSError *error, FAuthData *authData) {
|
|
copyCallback->Run(toMojoError(error), toMojoAuthData(authData));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::Unauth(const UnauthCallback& callback) {
|
|
[client_ unauth];
|
|
callback.Run(toMojoError(nullptr));
|
|
}
|
|
|
|
void FirebaseImpl::GetChild(
|
|
const mojo::String& path,
|
|
mojo::InterfaceRequest<Firebase> request) {
|
|
FirebaseImpl *child = new FirebaseImpl(request.Pass());
|
|
child->client_ = [[client_ childByAppendingPath:@(path.data())] retain];
|
|
}
|
|
|
|
void FirebaseImpl::GetParent(mojo::InterfaceRequest<Firebase> request) {
|
|
FirebaseImpl *parent = new FirebaseImpl(request.Pass());
|
|
parent->client_ = [[client_ parent] retain];
|
|
}
|
|
|
|
void FirebaseImpl::GetRoot(mojo::InterfaceRequest<::firebase::Firebase> request) {
|
|
FirebaseImpl *root = new FirebaseImpl(request.Pass());
|
|
root->client_ = [[client_ root] retain];
|
|
}
|
|
|
|
void FirebaseImpl::SetValue(const mojo::String& jsonValue,
|
|
int32_t priority,
|
|
bool hasPriority,
|
|
const SetValueCallback& callback) {
|
|
SetValueCallback *copyCallback =
|
|
new SetValueCallback(callback);
|
|
NSData *data = [@(jsonValue.data()) dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSError *error;
|
|
NSDictionary *valueDictionary = [NSJSONSerialization JSONObjectWithData:data
|
|
options:0
|
|
error:&error];
|
|
id value = [valueDictionary valueForKey:@"value"];
|
|
void (^completionBlock)(NSError *, ::Firebase* ref) = ^(NSError* error, ::Firebase* ref) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
};
|
|
if (valueDictionary != nil) {
|
|
if (hasPriority) {
|
|
[client_ setValue:value
|
|
andPriority:@(priority)
|
|
withCompletionBlock:completionBlock];
|
|
} else {
|
|
[client_ setValue:value withCompletionBlock:completionBlock];
|
|
}
|
|
} else {
|
|
completionBlock(error, client_);
|
|
}
|
|
}
|
|
|
|
void FirebaseImpl::RemoveValue(const RemoveValueCallback& callback) {
|
|
RemoveValueCallback *copyCallback =
|
|
new RemoveValueCallback(callback);
|
|
[client_ removeValueWithCompletionBlock:^(NSError *error, ::Firebase *ref) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::Push(mojo::InterfaceRequest<Firebase> request,
|
|
const PushCallback& callback) {
|
|
FirebaseImpl *child = new FirebaseImpl(request.Pass());
|
|
child->client_ = [[client_ childByAutoId] retain];
|
|
callback.Run(base::SysNSStringToUTF8(child->client_.key));
|
|
}
|
|
|
|
void FirebaseImpl::SetPriority(int32_t priority,
|
|
const SetPriorityCallback& callback) {
|
|
SetPriorityCallback *copyCallback =
|
|
new SetPriorityCallback(callback);
|
|
[client_ setPriority:@(priority)
|
|
withCompletionBlock:^(NSError *error, ::Firebase *ref) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::CreateUser(const mojo::String& email,
|
|
const mojo::String& password,
|
|
const CreateUserCallback& callback) {
|
|
CreateUserCallback *copyCallback =
|
|
new CreateUserCallback(callback);
|
|
[client_ createUser:@(email.data())
|
|
password:@(password.data())
|
|
withValueCompletionBlock:^(NSError *error, NSDictionary *valueDictionary) {
|
|
NSData *data = [NSJSONSerialization dataWithJSONObject:valueDictionary
|
|
options:0
|
|
error:nil];
|
|
if (data != nil) {
|
|
NSString *jsonValue = [[NSString alloc] initWithData:data
|
|
encoding:NSUTF8StringEncoding];
|
|
copyCallback->Run(toMojoError(error), base::SysNSStringToUTF8(jsonValue));
|
|
} else {
|
|
copyCallback->Run(toMojoError(error), nullptr);
|
|
}
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::ChangeEmail(const mojo::String& oldEmail,
|
|
const mojo::String& password,
|
|
const mojo::String& newEmail,
|
|
const ChangeEmailCallback& callback) {
|
|
ChangeEmailCallback *copyCallback =
|
|
new ChangeEmailCallback(callback);
|
|
[client_ changeEmailForUser:@(oldEmail.data())
|
|
password:@(password.data())
|
|
toNewEmail:@(newEmail.data())
|
|
withCompletionBlock:^(NSError *error) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::ChangePassword(
|
|
const mojo::String& newPassword,
|
|
const mojo::String& email,
|
|
const mojo::String& oldPassword,
|
|
const ChangePasswordCallback& callback) {
|
|
ChangePasswordCallback *copyCallback =
|
|
new ChangePasswordCallback(callback);
|
|
[client_ changePasswordForUser:@(email.data())
|
|
fromOld:@(oldPassword.data())
|
|
toNew:@(newPassword.data())
|
|
withCompletionBlock:^(NSError *error) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::RemoveUser(const mojo::String& email,
|
|
const mojo::String& password,
|
|
const RemoveUserCallback& callback) {
|
|
RemoveUserCallback *copyCallback =
|
|
new RemoveUserCallback(callback);
|
|
[client_ removeUser:@(email.data())
|
|
password:@(password.data())
|
|
withCompletionBlock:^(NSError *error) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseImpl::ResetPassword(const mojo::String& email,
|
|
const ResetPasswordCallback& callback) {
|
|
ResetPasswordCallback *copyCallback =
|
|
new ResetPasswordCallback(callback);
|
|
[client_ resetPasswordForUser:@(email.data())
|
|
withCompletionBlock:^(NSError *error) {
|
|
copyCallback->Run(toMojoError(error));
|
|
delete copyCallback;
|
|
}];
|
|
}
|
|
|
|
void FirebaseFactory::Create(
|
|
mojo::ApplicationConnection* connection,
|
|
mojo::InterfaceRequest<::firebase::Firebase> request) {
|
|
new FirebaseImpl(request.Pass());
|
|
}
|
|
|
|
} // namespace firebase
|
|
} // namespace services
|
|
} // namespace sky
|