GVKun编程网logo

为什么Appbase在返回正确的项目之前会返回“ undefined”?

22

以上就是给各位分享为什么Appbase在返回正确的项目之前会返回“undefined”?,同时本文还将给你拓展ajax–模拟apiinreactredux-thunk项目返回undefined、and

以上就是给各位分享为什么Appbase在返回正确的项目之前会返回“ undefined”?,同时本文还将给你拓展ajax – 模拟api in react redux-thunk项目返回undefined、android – if语句在从firebase检索数据时没有返回正确的元素、android – 在测试购买的情况下,为什么Google应用内结算会返回正确的orderId?、BottomAppBar菜单中不正确的项目位置错误等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

为什么Appbase在返回正确的项目之前会返回“ undefined”?

为什么Appbase在返回正确的项目之前会返回“ undefined”?

我正在将AppBase.io作为数据库使用,但我不明白为什么该组件在获得项目后会呈现两次?似乎AppBase“数据库” 首先返回 undefined
,然后返回 正确的项目 。有人知道为什么吗?查看示例,我得到2条日志。

在此组件中,我需要从数据库中获取一个项目并进行渲染(没什么特别的)。

感谢您的解释。

var appbaseRef = new Appbase({  url: "https://JHtFTzy4H:d083068b-596c-489d-9244-8db2ed316e79@scalr.api.appbase.io",  app: "winwin"});class ItemFull extends React.Component {  constructor() {    super();    this.state = {      item: ''''    }  }  componentWillMount() {    appbaseRef.get({      type: "items",      id: ''AWI5K7Q-5Q83Zq9GZnED''    }).on(''data'', (response) => {      this.setState({        item: response      });    }).on(''error'', function(error) {      console.log(error)    })  }  render() {    console.log(this.state.item._id, ''<-- console_log'');    return (<div></div>);  }}ReactDOM.render(<ItemFull /> , document.getElementById(''root''));<script src="https://cdnjs.cloudflare.com/ajax/libs/appbase-js/2.2.11/appbase.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id="root"></div>

答案1

小编典典

没有。您在开始异步调用componentWillMount不托起渲染过程(这是好的),所以render在调用完成之前调用,因此this.state.item._idundefined因为在这一点上,this.state.item''''(你在构造函数中设置的值)。

这完全正常,只需确保在尚无信息的情况下以适当的方式呈现组件即可,例如:

var appbaseRef = new Appbase({  url: "https://JHtFTzy4H:d083068b-596c-489d-9244-8db2ed316e79@scalr.api.appbase.io",  app: "winwin"});class ItemFull extends React.Component {  constructor() {    super();    this.state = {      item: ''''    }  }  componentWillMount() {    appbaseRef.get({      type: "items",      id: ''AWI5K7Q-5Q83Zq9GZnED''    }).on(''data'', (response) => {      this.setState({        item: response      });    }).on(''error'', function(error) {      console.log(error)    })  }  render() {    return <div>{this.state.item._id ? this.state.item._id : "loading..."}</div>;  }}ReactDOM.render(<ItemFull />, document.getElementById(''root''));<script src="https://cdnjs.cloudflare.com/ajax/libs/appbase-js/2.2.11/appbase.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id="root"></div>

如果在获得该信息之前根本不应该渲染该组件,那么您就在错误的位置提出了请求。:-)您需要在父组件中请求它,并且仅在拥有信息(在中传递信息props)时才呈现此组件,如下所示:

var appbaseRef = new Appbase({  url: "https://JHtFTzy4H:d083068b-596c-489d-9244-8db2ed316e79@scalr.api.appbase.io",  app: "winwin"});class ParentComponent extends React.Component {  constructor(...args) {    super(...args);    this.state = {item: null};  }  componentWillMount() {    appbaseRef.get({      type: "items",      id: ''AWI5K7Q-5Q83Zq9GZnED''    }).on(''data'', (response) => {      this.setState({        item: response      });    }).on(''error'', function(error) {      console.log(error)    })  }  render() {    return this.state.item ? <ItemFull item={this.state.item} /> : <div>loading...</div>;  }}class ItemFull extends React.Component {  render() {    return <div>{this.props.item._id}</div>;  }}ReactDOM.render( <ParentComponent /> , document.getElementById(''root''));<script src="https://cdnjs.cloudflare.com/ajax/libs/appbase-js/2.2.11/appbase.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script><div id="root"></div>

ajax – 模拟api in react redux-thunk项目返回undefined

ajax – 模拟api in react redux-thunk项目返回undefined

我在redux世界中很新,还没有一个项目以 ducks方式构建.我试图理解它并使用它来制作一个模拟API,因为我还没有准备好后端.我正在使用遗留代码,我想弄清楚.有一个名为data的文件夹,它有一个duck和一个backendApi文件. Duck文件看起来像这样.

数据/ duck.jsx

import { createSelector } from 'reselect';
import { createReduxApi } from './backendApi';

const getDataContext = state => state.default.dataContext;

const backendReduxApi = createBackendReduxApi(getDataContext);

// Action creators
export const makeRestApiRequest = endpointName => backendReduxApi .makeRequestActionCreator(endpointName);

export const resetRestApi = endpointName => backendReduxApi .makeResetActionCreator(endpointName);

// Reducers
export const dataReducer = backendReduxApi .createReducer();

// Selectors
const getRestApiState = endpointName => backendReduxApi .getEndpointState(endpointName);
export const getRestApiData = endpointName => createSelector([getRestApiState(endpointName)],apiState => apiState.data);
export const getRestApiMeta = endpointName => createSelector([getRestApiState(endpointName)],apiState => apiState.Meta);
export const getRestApiError = endpointName => createSelector([getRestApiState(endpointName)],apiState => apiState.error);
export const getRestApiStarted = endpointName => createSelector([getRestApiState(endpointName)],apiState => apiState.started);
export const getRestApiFinished = endpointName => createSelector([getRestApiState(endpointName)],apiState => apiState.finished);

backendApi.jsx文件如下所示:

数据/ backendApi.jsx

import ReduxRestApi from './rest/ReduxRestApi';

export const BackendApi = { // NOSONAR
  LANGUAGE_FILE: 'languageFile',EMPLOYEE: 'employee',};

const backendReduxApiBuilder = ReduxRestApi.build()
  /* /api */

  /* /api/employee */
  .withGet('/myproject/api/employee',BackendApi.EMPLOYEE)

  /* /language*/
  .withGet('/myproject/language/nb_NO.json',BackendApi.LANGUAGE_FILE)

export const createBackendReduxApi = restApiSelector => backendReduxApiBuilder
  .withRestApiSelector(restApiSelector)
  .create();

然后在data / rest文件夹中我有4个文件:ReduxRestApi,restConfig,RestDuck和restMethods.

数据/休息/ ReduxRestApi.jsx

import { combineReducers } from 'redux';
import { get,post,postAndOpenBlob } from './restMethods';
import RestDuck from './RestDuck';

class ReduxRestApi {
  constructor(endpoints,getRestApiState) {
    this.createReducer = this.createReducer.bind(this);
    this.getEndpoint = this.getEndpoint.bind(this);
    this.makeRequestActionCreator = this.makeRequestActionCreator.bind(this);
    this.makeResetActionCreator = this.makeResetActionCreator.bind(this);
    this.getEndpointState = this.getEndpointState.bind(this);
    this.ducks = endpoints.map(({ name,path,restMethod }) => new RestDuck(name,restMethod,getRestApiState));
  }

  createReducer() {
    const reducers = this.ducks
      .map(duck => ({ [duck.name]: duck.reducer }))
      .reduce((a,b) => ({ ...a,...b }),{});
    return combineReducers(reducers);
  }

  getEndpoint(endpointName) {
    return this.ducks.find(duck => duck.name === endpointName)
      || { actionCreators: {} };
  }

  makeRequestActionCreator(endpointName) {
    return this.getEndpoint(endpointName).actionCreators.execRequest;
  }

  makeResetActionCreator(endpointName) {
    return this.getEndpoint(endpointName).actionCreators.reset;
  }

  getEndpointState(endpointName) {
    return this.getEndpoint(endpointName).stateSelector;
  }

  static build() {
    class RestApiBuilder {
      constructor() {
        this.withGet = this.withGet.bind(this);
        this.withPost = this.withPost.bind(this);
        this.withPostAndOpenBlob = this.withPostAndOpenBlob.bind(this);
        this.withRestApiSelector = this.withRestApiSelector.bind(this);
        this.endpoints = [];
      }

      withGet(path,name) {
        this.endpoints.push({ path,name,restMethod: get });
        return this;
      }

      withPost(path,restMethod: post });
        return this;
      }

      withPostAndOpenBlob(path,restMethod: postAndOpenBlob });
        return this;
      }

      withRestApiSelector(restApiSelector) {
        this.restApiSelector = restApiSelector;
        return this;
      }

      create() {
        return new ReduxRestApi(
          this.endpoints,this.restApiSelector
        );
      }
    }

    return new RestApiBuilder();
  }
}

export default ReduxRestApi;

restConfig.jsx

import axios from 'axios';
import { removeErrorMessage,showErrorMessage } from '../../app/duck';
import { is401Error,isHandledError } from '../../app/ErrorTypes';

const isDevelopment = process.env.NODE_ENV === 'development';

const configureRequestInterceptors = (store) => {
  const onRequestAccepted = (config) => {
    store.dispatch(removeErrorMessage());
    return config;
  };

  const onRequestRejected = error => Promise.reject(error);

  axios.interceptors.request.use(onRequestAccepted,onRequestRejected);
};

const configureResponseInterceptors = (store) => {
  const onSuccessResponse = response => response;

  const onErrorResponse = (error) => {
    if (is401Error(error) && !isDevelopment) {
      window.location.reload();
    }
    if (!isHandledError(error)) {
      store.dispatch(showErrorMessage(error));
    }
    return Promise.reject(error);
  };

  axios.interceptors.response.use(onSuccessResponse,onErrorResponse);
};

const configureRestInterceptors = (store) => {
  configureRequestInterceptors(store);
  configureResponseInterceptors(store);
};

export default configureRestInterceptors;

数据/休息/ RestDuck.jsx

import { createSelector } from 'reselect';

import { get,getBlob,postAndOpenBlob,postBlob } from './restMethods';

/**
 * getmethodName
 * Helper function that maps given AJAX-method to a name
 *
 * Ex. getmethodName(getBlob) -> 'GET'
 */
const getmethodName = (restMethod) => {
  switch (restMethod) {
    case get:
    case getBlob:
      return 'GET';
    case post:
    case postBlob:
    case postAndOpenBlob:
      return 'POST';
    default:
      return '';
  }
};

/**
 * createRequestActionType
 * Helper function to generate actionType for actions related to AJAX calls
 *
 * Ex: createRequestActionType('fetchEmployee','ERROR',get,'/myproject/api/employee') -> '@@REST/fetchEmployee GET /myproject/api/employeeERROR'
 */
const createRequestActionType = (name,qualifier,restMethod = '',path = '') => [`@@REST/${name}`,getmethodName(restMethod),qualifier]
  .filter(s => s !== '')
  .join(' ');

/**
 * createRequestActionTypes
 * Helper function to generate ActionTypes for a given AJAX method and resource.
 *
 * Ex. createRequestActionType(fetchEmployee,'/myproject/api/employee') -> {
 *   reset: '@@REST GET /myproject/api/employee RESET',*   requestStarted: '@@REST GET /myproject/api/employee STARTED',*   requestError: '@@REST GET /myproject/api/employee ERROR',*   requestFinished: '@@REST GET /myproject/api/employee FINISHED',* }
 */
const createRequestActionTypes = (name,path) => ({
  reset: createRequestActionType(name,'RESET'),requestStarted: createRequestActionType(name,'STARTED',path),requestError: createRequestActionType(name,requestFinished: createRequestActionType(name,'FINISHED',path)
});

/**
 * createRequestThunk
 * Helper function that generates a thunk that performs an AJAX call specified by 'restMethod' and 'restEndpoint'
 *
 * When the thunk is running,the action 'requestStarted' will be dispatched immediately.
 * Then,it performs the AJAX call that returns a promise.
 *  If the call goes well,the action 'requestFinished' will be dispatched with data from the call.
 * If the call fails,the action 'requestError' is dispatched with the contents of the error.
 */
const createRequestThunk = (restMethod,restEndpoint,requestStarted,requestFinished,requestError) => (
  (params,options = {}) => (dispatch) => {
    dispatch(requestStarted(params,options));
    return restMethod(restEndpoint,params)
      .catch((error) => {
        const data = error.response && error.response.data ? error.response.data : error;
        dispatch(requestError(data));
        return Promise.reject(error);
      })
      .then((response) => {
        dispatch(requestFinished(response.data));
        return response;
      });
  }
);

/**
 * createRequestActionCreators
 * Helper function that creates action creators 'requestStarted','requestFinished' and 'requestError',* @see createRequestThunkCreator
 */
const createRequestActionCreators = (restMethod,actionTypes) => {
  const reset = () => ({ type: actionTypes.reset });
  const requestStarted = (params,options = {}) => ({ type: actionTypes.requestStarted,payload: { params,timestamp: Date.Now() },Meta: { options } });
  const requestFinished = data => ({ type: actionTypes.requestFinished,payload: data });
  const requestError = error => ({ type: actionTypes.requestError,payload: error });
  const execRequest = createRequestThunk(restMethod,requestError);
  return {
    reset,requestError,execRequest
  };
};

/**
 * createRequestReducer
 *
 * Helper function that creates a reducer for an AJAX call.
 * Reducer alters the state of the actions with the name defined by
 *   actionTypes.requestStarted
 *   actionTypes.requestFinished
 *   actionTypes.requestError
 */
const createRequestReducer = (restMethod,resourceName,actionTypes) => {
  const initialState = {
    data: undefined,Meta: undefined,error: undefined,started: false,finished: false
  };

  return (state = initialState,action = {}) => {
    switch (action.type) {
      case actionTypes.requestStarted:
        return {
          ...initialState,data: action.Meta.options.keepData ? state.data : initialState.data,started: true,Meta: action.payload
        };
      case actionTypes.requestFinished:
        return {
          ...state,finished: true,data: action.payload
        };
      case actionTypes.requestError:
        return {
          ...state,error: action.payload
        };
      case actionTypes.reset:
        return {
          ...initialState
        };
      default:
        return state;
    }
  };
};

/**
 * RestDuck
 * Class that offers action types,action creators,reducers and selectors for an AJAX call.
 * @see createRequestActionTypes
 * @see createRequestActionCreators
 * @see createRequestReducer
 *
 * Ex.
 * const getEmployeeDuck = new RestDuck(execGetRequest,'employee',GET_EMPLOYEE_SERVER_URL);
 * // Action creators
 * export const fetchEmployee = getEmployeeDuck.actionCreators.execRequest;
 * // Reducer
 * export const dataReducer = combineReducers(
 *   ...,*   getEmployeeDuck.reducer,* }
 * // Selectors
 * export const getDataContext = state => state.default.dataContext;
 * export const getEmployeeData = getEmployeeDuck.selectors.getRequestData(getDataContext);
 * export const getEmployeeStarted = getEmployeeDuck.selectors.getRequestStarted(getDataContext);
 * ...
 */
class RestDuck {
  constructor(name,getApiContext) {
    this.restMethod = restMethod;
    this.name = name;
    this.path = path;
    this.getApiContext = getApiContext;
    this.$$duck = {}; // for class internal use
  }

  get actionTypes() {
    if (!this.$$duck.actionTypes) {
      this.$$duck.actionTypes = createRequestActionTypes(this.name,this.restMethod,this.path);
    }
    return this.$$duck.actionTypes;
  }

  get actionCreators() {
    if (!this.$$duck.actionCreators) {
      this.$$duck.actionCreators = createRequestActionCreators(this.restMethod,this.path,this.actionTypes);
    }
    return this.$$duck.actionCreators;
  }

  get reducer() {
    if (!this.$$duck.reducer) {
      this.$$duck.reducer = createRequestReducer(this.restMethod,this.name,this.actionTypes);
    }
    return this.$$duck.reducer;
  }

  get stateSelector() {
    return createSelector([this.getApiContext],restApiContext => restApiContext[this.name]);
  }
}

export default RestDuck;

数据/休息/ restMethods.jsx

import axios,{ CancelToken } from 'axios';

const openPreview = (data) => {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(data);
  } else {
    window.open(URL.createObjectURL(data));
  }
};

const cancellable = (config) => {
  let cancel;
  const request = axios({
    ...config,cancelToken: new CancelToken((c) => { cancel = c; })
  });
  request.cancel = cancel;
  return request.catch(error => (axios.isCancel(error) ? Promise.reject(new Error(null)) : Promise.reject(error)));
};

const defaultHeaders = {
  'Cache-Control': 'no-cache',Pragma: 'no-cache',Expires: 0
};

const defaultPostHeaders = {
  'Content-Type': 'application/json'
};

export const get = (url,params,responseType = 'json') => cancellable({
  url,responseType,method: 'get',headers: {
    ...defaultHeaders
  }
});

export const post = (url,data,data: JSON.stringify(data),method: 'post',headers: {
    ...defaultHeaders,...defaultPostHeaders
  },cache: false
});

export const getBlob = (url,params) => get(url,'blob');

export const postBlob = (url,data) => post(url,'blob');

export const postAndOpenBlob = (url,data) => postBlob(url,data)
  .then((response) => {
    openPreview(response.data);
    return {
      ...response,data: 'blob opened as preview' // Don't waste memory by storing blob in state
    };
  });

我不知道在这个结构中如何放置以及如何模拟api调用.我正在考虑制作一个类似于这个one的模拟api,在那里我会模仿ajax调用并将它们存储在redux中,但是不知道如何在这种设置中执行此操作?

我尝试使用mockApi文件夹而不是使用restMethods来使用我将编写将解析mockData的promises的文件.这是我的尝试:

mockRestMethods

const employee = {
  name: 'Joe Doe'
}
const data = {
  employee 
};

export const get = item => new Promise((resolve) => {
  setTimeout(() => {
    resolve({ data: data[item] });
  },1000);
});

但是,如果我在RestDuck文件中的createRequestThunk函数内检查返回的内容作为response.data,我得到数据:undefined there.为什么,我做错了什么?

我可能有这个错误,但似乎你正在取代

export const get =(url,responseType =’json’)=>撤销({

with export const get = item =>新的Promise((resolve)=> {具有不同的API.

无论如何,您是否尝试在mock get函数中记录item的值.我猜它不是“员工”,这是数据中唯一的属性.

Yes,that was my goal,to replace the call that was pointing to the backend API,with the call where I would return the mock data. I have tried to log the value of the item,but I get undefined

好的,所以那里有很多抽象.我建议首先使用返回promise的版本替换get in data / rest / restMethods.jsx,让它工作,然后将其分解.这样你就不会立刻处理太多未知数.

android – if语句在从firebase检索数据时没有返回正确的元素

android – if语句在从firebase检索数据时没有返回正确的元素

我在Firebase Database中有一些数据,如下所示:

app
 -child1
   -uniqueId1
     -pId1
     -lId1
   -uniqueId2
     -pId2
     -lId2
   -uniqueId3
     -pId3
     -lId3
   -uniqueId4
     -pId4
     -lId4
   -uniqueId5
     -pId5
     -lId5
   -uniqueId6
     -pId6
     -lId6
 -child2
   -uniqueIdA1
     -uniqueId7
     -uniqueId8
     -uniqueId9
     -uniqueId10
     -uniqueId11
     -uniqueId1
     -uniqueId2
     -uniqueId3
     -uniqueId4
     -uniqueId5

我正在检索child1的数据,如下所示:

public void fMethod(final String fID,final String blackListedId) {
        mDatabase.child("child1").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot,String s) {
                if (dataSnapshot.getValue() != null) {
                    Profile profile = dataSnapshot.getValue(Profile.class);
                    String pID = profile.getPID();
                    String lID = profile.getLID();
                    if (!pID.trim().equals(Accesstoken.getCurrentAccesstoken().getUserId().trim())) {
                        if (pID.trim().equals(fID.trim())) {
                            if (!lID.trim().equals(blackListedId.trim())) {
                            // populate the view with elements which meet this condition/requirement

                            String listingID = profile.getlID();
                            Log.d("LISTING_IDS",listingID);

                            } else {
                                Log.d("dataSnapshot","null1");
                            }
                        } else {
                            Log.d("dataSnapshot","null2");
                        }
                    } else {
                        Log.d("dataSnapshot","null3");
                    }
                } else {
                    Log.d("dataSnapshot","null4");
                }
            }
            ...
            ...
            ...
    }

和child2的数据如下:

public void fData(final String fID) {

        mDatabase.child("child2").child(Accesstoken.getCurrentAccesstoken().getUserId()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                if (dataSnapshot.getValue() != null) {
                    for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
                        String blackListedId = childSnapshot.getValue().toString();
                        fMethod(fID,blackListedId);
                    }
                } else {
                    fMethod(fID,"");
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

然后在另一个代码中我正在检索fID并在那里调用fData()方法.

我记录了我从数据库中获取的所有ID:

D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId1
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId2
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId3
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId4
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5
D/LISTING_IDS: uniqueId5

这是Profile.java文件的代码:https://gist.github.com/HammadNasir/a196bcdc6dccbf69657fca528443e680

问题是在fMethod()的if语句中,条件是!lID.trim().equals(blackListedId.trim()所以,正如你在数据库中看到的那样,我应该得到child1下的所有uniqueIds,除了uniqueId3和uniqueId7因为这两个也存在于child2中,但我得到的所有uniqueIds除了uniqueId3和uniqueId7两次,uniqueId3和uniqueId7一次.

另外需要注意的是,当我将该条件设置为lID.trim().equals(blackListedId.trim()时,我只得到符合此要求的2个ID,即uniqueId3和uniqueId7,如果child2有在uniqueId11下只有1个id然后我得到所有uniqueIds,除了这里的那个,但有2个或更多id导致问题.

我希望你能解决我的问题.我尽力用尽可能少的代码来解释它.

为什么!lID.trim().equals(blackListedId.trim()返回意外的id,我怎么才能得到满足这个条件的id?

解决方法

子2的addListenerForSingleValueEvent将始终被调用两次 – 一次设置时,第二次读取所有数据时.因此,当它第一次被调用时,它最终会调用fMethod(fID,“”),这是你从Child 1获取所有ID的地方,包括3和7.但是下次调用它时,它会正常形容它.因此,如果从child2 ValueEventListener中删除“else”条件,我认为它应该可以正常工作.

如果我理解你的问题并回答它,请告诉我.如果没有,请随时解释更多细节.

android – 在测试购买的情况下,为什么Google应用内结算会返回正确的orderId?

android – 在测试购买的情况下,为什么Google应用内结算会返回正确的orderId?

Google表示如果购买是测试购买,您将收到空订单ID.但是我们得到了正确的orderId,所以问题是如何检查购买是否是测试购买.为什么要获得orderId?

解决方法

我猜您正在检查json响应,而不是包含订单号的电子邮件中的Google Play订单收据.

如果是测试购买,则JSON响应不应包含orderId.已经确认了几次.确保您用于测试购买的帐户包含在Google Play开发者控制台>中的许可测试帐户中.应用设置>帐户详细信息,然后在“许可证测试”部分.

检查here

When your in-app Billing implementation is ready,you can test
purchasing of your in-app SKUs in two ways:

Test purchases,which let your selected license-test users purchase
your in-app products without any resulting charges to the user. Test
purchases can be used in alpha/beta releases only.

Real purchases,which let regular users make real purchases of your in-app products with actual charges to the user’s payment instruments.

BottomAppBar菜单中不正确的项目位置错误

BottomAppBar菜单中不正确的项目位置错误

如何解决BottomAppBar菜单中不正确的项目位置错误?

当我使用BottomAppBar菜单更改它时,我的菜单出现问题 bottomAppBar.setFabAlignmentModeAndReplaceMenu(BottomAppBar.FAB_ALIGNMENT_MODE_END,R.menu.detail_page_menu);com.google.android.material:material:1.3.0-alpha02中可用的功能。

我有2个菜单R.menu.menu_mainR.menu.detail_page_menu,我在BottomAppBar中使用这些菜单,它们在片段发生变化时进行更改。

两个菜单都包含2个元素。

当我切换菜单时,有时会出现问题(这使我认为这是一个错误)。

这是菜单应显示的正确方式(并且仅在第一次或第二次出现,有点随机):

correct menu

这是第一次或第二次打开该片段和菜单开关之后发生的情况:

bugged menu

这是我的BottomAppBar布局代码:

<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.MainActivity">

<FrameLayout
    android:id="@+id/fragment1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="UnkNownIdInLayout"
    android:layout_marginBottom="38dp"
    />

<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:layout_alignParentBottom="true"
    android:id="@+id/coord"
    >

    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:fabAlignmentMode="center"
        app:fabAnimationMode="scale"
        app:contentInsetLeft="0dp"
        app:contentInsetStart="0dp"
        app:backgroundTint="@color/colorAccent"
        android:theme="@style/Theme.MaterialComponents"
        app:hideOnScroll="true"
        app:layout_scrollFlags="scroll|enteralways"
        />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:maxImageSize="36dp"
        android:src="@drawable/money"
        app:backgroundTint="@color/colorPrimary"
        app:layout_anchor="@id/bar" />

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/snackbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:rotation=''180''
        />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

这是当我在MainActivity.java中更改菜单时

    public void setFabSecondPosition(){
    // Hide navigation drawer icon
    // Move FAB from the center of BottomAppBar to the end of it
    bottomAppBar.setFabAlignmentModeAndReplaceMenu(BottomAppBar.FAB_ALIGNMENT_MODE_END,R.menu.detail_page_menu);
    // Replace the action menu
    // Change FAB icon
    fab.setimageDrawable(fabIconSecond);
}

public void setFabMainPosition(){
    bottomAppBar.setFabAlignmentModeAndReplaceMenu(BottomAppBar.FAB_ALIGNMENT_MODE_CENTER,R.menu.menu_main);
    fab.setimageDrawable(fabIconFirst);
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

我们今天的关于为什么Appbase在返回正确的项目之前会返回“ undefined”?的分享就到这里,谢谢您的阅读,如果想了解更多关于ajax – 模拟api in react redux-thunk项目返回undefined、android – if语句在从firebase检索数据时没有返回正确的元素、android – 在测试购买的情况下,为什么Google应用内结算会返回正确的orderId?、BottomAppBar菜单中不正确的项目位置错误的相关信息,可以在本站进行搜索。

本文标签: